- 用数组实现的队列的dequeue方法用到了数组的shift方法,时间复杂度为O(n),而用链表实现的dequeue方法时间复杂度只为O(1),因为我们有保存指向头部的指针,所以直接让head = head.next就能实现dequeue,总体来说用链表实现队列效率更高。
首先列好基本需求
// 链表里每个元素用节点表示
class Node {
value;
next;
constructor(value){
this.value = value;
}
}
// 三个私有变量:
// 1. 存指向头部的指针,为了dequeue
// 2. 存指向尾部的指针,为了enqueue
// 3. 存队列长度,为了实时更新长度
class Queue {
#head;
#tail;
#size;
constructor(){}
//入队方法
enqueue(value){}
//出队方法
dequeue(){}
//清除队列方法
clear(){}
//获取队列大小,用getter
get size(){}
// 用Symbol.iterator和Generator函数来实现对队列的迭代
* [Symbol.iterator](){}
}
Array, Map, Set, String都有内置的迭代器,然而有些情况,你可能需要对一个对象进行迭代。我们可以用Symbol.iterator来自定义实现一个迭代器,同时他还能被for...of...迭代。
实现具体方法
class Node {
value;
next;
constructor(value){
this.value = value;
}
}
class Queue {
#head;
#tail;
#size;
constructor() {
this.clear();
}
enqueue(value) {
const node = new Node(value);
if (this.#head) {
this.#tail.next = node;
this.#tail = node;
} else {
this.#head = node;
this.#tail = node;
}
this.#size++;
}
dequeue() {
if(!this.#head) return;
const first = this.#head;
this.#head = this.#head.next;
this.#size--;
return first.value;
}
clear() {
this.#head = undefined;
this.#tail = undefined;
this.#size = 0;
}
get size(){
return this.#size;
}
* [Symbol.iterator]() {
let curr = this.#head;
while (curr) {
yield curr.value;
curr = curr.next;
}
}
}
使用
const queue = new Queue();
queue.enqueue('a');
queue.enqueue('b');
console.log(queue.size);
// output: 2
console.log(...queue)
// output: a b
for(const item of queue){
console.log(item)
}
// output: a
// b
console.log(queue.dequeue());
// output: a