在JavaScript中实现堆栈和队列的最佳方法是什么?
我想做调车场算法我需要这些数据结构。
在JavaScript中实现堆栈和队列的最佳方法是什么?
我想做调车场算法我需要这些数据结构。
当前回答
我在实现BFS时遇到了这个线程。在疑惑为何表现如此糟糕之后,我做了一些调查。array.shift()通常在O(n)中运行,这将我的BFS运行时从O(V+E)增加到O(V^2+E)。
我没有从头开始实现一个队列,而是使用了npm包双端队列,它与之前使用的数组方法兼容,工作起来很有魅力。 deque可以用作堆栈或队列。
//import package
import Deque from 'double-ended-queue';
//create queue
let queue = new Deque();
//append
queue.push(item);
//dequeue (get first item inserted)
let firstItem = queue.shift();
//pop (get last item inserted)
let lastItem = queue.pop();
其他回答
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技巧”
下面是一个相当简单的队列实现,有两个目标:
与array.shift()不同,您知道这个出队列方法需要常数时间(O(1))。 为了提高速度,这种方法使用的分配比链表方法少得多。
堆栈实现只共享第二个目标。
// Queue
function Queue() {
this.q = new Array(5);
this.first = 0;
this.size = 0;
}
Queue.prototype.enqueue = function(a) {
var other;
if (this.size == this.q.length) {
other = new Array(this.size*2);
for (var i = 0; i < this.size; i++) {
other[i] = this.q[(this.first+i)%this.size];
}
this.first = 0;
this.q = other;
}
this.q[(this.first+this.size)%this.q.length] = a;
this.size++;
};
Queue.prototype.dequeue = function() {
if (this.size == 0) return undefined;
this.size--;
var ret = this.q[this.first];
this.first = (this.first+1)%this.q.length;
return ret;
};
Queue.prototype.peek = function() { return this.size > 0 ? this.q[this.first] : undefined; };
Queue.prototype.isEmpty = function() { return this.size == 0; };
// Stack
function Stack() {
this.s = new Array(5);
this.size = 0;
}
Stack.prototype.push = function(a) {
var other;
if (this.size == this.s.length) {
other = new Array(this.s.length*2);
for (var i = 0; i < this.s.length; i++) other[i] = this.s[i];
this.s = other;
}
this.s[this.size++] = a;
};
Stack.prototype.pop = function() {
if (this.size == 0) return undefined;
return this.s[--this.size];
};
Stack.prototype.peek = function() { return this.size > 0 ? this.s[this.size-1] : undefined; };
下面是一个队列的链表版本,它也包括最后一个节点,这是@perkins建议的,也是最合适的。
// QUEUE Object Definition
var Queue = function() {
this.first = null;
this.last = 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){ // for empty list first and last are the same
this.first = node;
this.last = node;
} else { // otherwise we stick it on the end
this.last.next=node;
this.last=node;
}
this.size += 1;
return node;
};
Queue.prototype.dequeue = function() {
if (!this.first) //check for empty list
return null;
temp = this.first; // grab top of list
if (this.first==this.last) {
this.last=null; // when we need to pop the last one
}
this.first = this.first.next; // move top of list down
this.size -= 1;
return temp;
};
使用两个堆栈构造一个队列。
O(1)用于入队和出队操作。
class Queue {
constructor() {
this.s1 = []; // in
this.s2 = []; // out
}
enqueue(val) {
this.s1.push(val);
}
dequeue() {
if (this.s2.length === 0) {
this._move();
}
return this.s2.pop(); // return undefined if empty
}
_move() {
while (this.s1.length) {
this.s2.push(this.s1.pop());
}
}
}
数组。
栈:
var stack = [];
//put value on top of stack
stack.push(1);
//remove value from top of stack
var value = stack.pop();
队列:
var queue = [];
//put value on end of queue
queue.push(1);
//Take first value from queue
var value = queue.shift();