在JavaScript中实现堆栈和队列的最佳方法是什么?
我想做调车场算法我需要这些数据结构。
在JavaScript中实现堆栈和队列的最佳方法是什么?
我想做调车场算法我需要这些数据结构。
当前回答
Javascript数组shift()很慢,特别是当包含很多元素时。我知道两种方法来实现平摊O(1)复杂度的队列。
首先是使用循环缓冲区和表加倍。我以前实现过这个。你可以在这里看到我的源代码 https://github.com/kevyuu/rapid-queue
第二种方法是使用两个堆栈。这是带有两个堆栈的队列的代码
function createDoubleStackQueue() {
var that = {};
var pushContainer = [];
var popContainer = [];
function moveElementToPopContainer() {
while (pushContainer.length !==0 ) {
var element = pushContainer.pop();
popContainer.push(element);
}
}
that.push = function(element) {
pushContainer.push(element);
};
that.shift = function() {
if (popContainer.length === 0) {
moveElementToPopContainer();
}
if (popContainer.length === 0) {
return null;
} else {
return popContainer.pop();
}
};
that.front = function() {
if (popContainer.length === 0) {
moveElementToPopContainer();
}
if (popContainer.length === 0) {
return null;
}
return popContainer[popContainer.length - 1];
};
that.length = function() {
return pushContainer.length + popContainer.length;
};
that.isEmpty = function() {
return (pushContainer.length + popContainer.length) === 0;
};
return that;}
这是使用jsPerf进行的性能比较
CircularQueue.shift() vs Array.shift()
http://jsperf.com/rapidqueue-shift-vs-array-shift
正如你所看到的,大数据集的速度要快得多
其他回答
Javascript有push和pop方法,它们操作在普通的Javascript数组对象上。
关于排队,请看这里:
http://safalra.com/web-design/javascript/queues/
Queues can be implemented in JavaScript using either the push and shift methods or unshift and pop methods of the array object. Although this is a simple way to implement queues, it is very inefficient for large queues — because of the methods operate on arrays, the shift and unshift methods move every element in the array each time they are called. Queue.js is a simple and efficient queue implementation for JavaScript whose dequeue function runs in amortized constant time. As a result, for larger queues, it can be significantly faster than using arrays.
As many have said: native array using push and pop is fine for a stack, but using shift for taking elements from a queue means that the remaining elements need to move, which is potentially slow. The idea of using two stacks to make a queue in kevinyu's answer is a nice idea to fix it, and of course that can be done with native-array-stacks as well. (Edit: there was actually already an answer by Yuki-Dreamer that does this, albeit less compactly. I didn't notice it until now because it was unfairly downvoted.)
下面是一个使用ES5/ES6特性的紧凑实现,它使队列对象的行为尽可能接近本机的push/shift变体,除了每次操作花费O(1)平摊时间:
const queue = () => {
const a = [], b = [];
return {
push: (...elts) => a.push(...elts),
shift: () => {
if (b.length === 0) {
while (a.length > 0) { b.push(a.pop()) }
}
return b.pop();
},
get length() { return a.length + b.length }
}
}
现在你可以做:
const q = queue();
q.push(8);
q.push(9);
q.push(10);
console.log(q.length); // outputs 3
console.log(q.shift()); // outputs 8
q.push(11);
console.log(q.shift()); // outputs 9
console.log(q.shift()); // outputs 10
console.log(q.shift()); // outputs 11
console.log(q.shift()); // outputs undefined
队列实现对长度使用getter语法,使其看起来像一个属性,并对push使用rest参数语法,以允许一次推送多个内容。如果你不想这样做,你可以用push: elt => a.push(elt),替换第4行。(但是请注意,你不能用push: a.push替换它,就像我自己第一次尝试的那样,结果非常奇怪:这是因为它导致本机push方法被调用,并设置为队列对象。)
var stack = [];
stack.push(2); // stack is now [2]
stack.push(5); // stack is now [2, 5]
var i = stack.pop(); // stack is now [2]
alert(i); // displays 5
var queue = [];
queue.push(2); // queue is now [2]
queue.push(5); // queue is now [2, 5]
var i = queue.shift(); // queue is now [5]
alert(i); // displays 2
摘自“9个你可能不知道的JavaScript技巧”
问候,
在Javascript中,栈和队列的实现如下:
堆栈:堆栈是一个容器,其中的对象是根据后进先出(LIFO)原则插入和删除的。
方法将一个或多个元素添加到数组的末尾,并返回数组的新长度。 方法从数组中删除最后一个元素并返回该元素。
队列:队列是根据先进先出(FIFO)原则插入和删除对象的容器(线性集合)。
方法将一个或多个元素添加到数组的开头。 Shift:该方法从数组中移除第一个元素。
let stack = []; stack.push(1);//[1] stack.push(2);//[1,2] stack.push(3);//[1,2,3] console.log('It was inserted 1,2,3 in stack:', ...stack); stack.pop(); //[1,2] console.log('Item 3 was removed:', ...stack); stack.pop(); //[1] console.log('Item 2 was removed:', ...stack); let queue = []; queue.push(1);//[1] queue.push(2);//[1,2] queue.push(3);//[1,2,3] console.log('It was inserted 1,2,3 in queue:', ...queue); queue.shift();// [2,3] console.log('Item 1 was removed:', ...queue); queue.shift();// [3] console.log('Item 2 was removed:', ...queue);
如果你想创建自己的数据结构,你可以创建自己的:
var Stack = function(){
this.top = null;
this.size = 0;
};
var Node = function(data){
this.data = data;
this.previous = null;
};
Stack.prototype.push = function(data) {
var node = new Node(data);
node.previous = this.top;
this.top = node;
this.size += 1;
return this.top;
};
Stack.prototype.pop = function() {
temp = this.top;
this.top = this.top.previous;
this.size -= 1;
return temp;
};
对于队列:
var Queue = function() {
this.first = null;
this.size = 0;
};
var Node = function(data) {
this.data = data;
this.next = null;
};
Queue.prototype.enqueue = function(data) {
var node = new Node(data);
if (!this.first){
this.first = node;
} else {
n = this.first;
while (n.next) {
n = n.next;
}
n.next = node;
}
this.size += 1;
return node;
};
Queue.prototype.dequeue = function() {
temp = this.first;
this.first = this.first.next;
this.size -= 1;
return temp;
};