本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。
本篇是源码共读第32期 | yocto-queue 队列 链表,点击了解本期详情
项目源码
应用场景
当我们在大型数组上执行大量的push和shift操作时应该使用该包来代替数组,数组的线性时间复杂度为O(n)而Queue具有恒定的时间复杂度O(1)
队列是有序的元素列表,其中元素插入到队列的末尾并从队列的前面删除。队列基于先进先出 (FIFO) 原则工作。
class Node
class Node {
// 当前节点值
value;
// 下一个节点
next;
constructor(value: any) {
this.value = value;
}
}
class Queue
class Queue {
// 定义私有字段
// 从作用域之外引用 `#` 名称、内部在未声明的情况下引用私有字段、
// 或尝试使用 `delete` 移除声明的字段都会抛出语法错误。
#head;
#tail;
#size;
constructor() {
// 重置私有字段值
this.clear();
}
// 入队
enqueue(value) {
// 创建一个节点
const node = new Node(value);
// 如果已存在头结点
if(this.#head) {
// 将尾节点的下一个赋值为node
// 在第一次入队时,head和tail指向同一个对象Node
// #head: { value: 1, next: { value: 2, next: undefined }}
// #tail: { value: 1, next: { value: 2, next: undefined }}
this.#tail.next = node;
// 更新尾节点
// #head: { value: 1, next: { value: 2, next: undefined }}
// #tail: { value: 2, next: undefined }
this.#tail = node;
} else {
// 反之将头结点和尾节点赋值为node
this.#head = node;
this.#tail = node;
}
// 队列长队加一
this.#size++;
}
// 出队
dequeue() {
const current = this.#head;
// 如果不存在head直接return
if(!current) {
return;
}
// 基于先进先出(FIFO)原则,从头节点开始
// 将当前head节点的next节点赋值给当前head
this.#head = this.#head.next;
// 队列长度减一
this.#size--;
// 返回已被删除的值
return current;
}
// 清空队列
clear() {
this.#head = undefined;
this.#tail = undefined;
this.#size = 0;
}
// 为queue定义一个迭代器,使对象Queue可被循环遍历
*[Symbol.iterator]() {
let current = this.#head;
while(current) {
// 输出当前值
yield current.value;
// 指向下一个节点
current = current.next;
}
}
}
总结
· 队列在处理大型数组时为更优选择
· [Symbol.iterator] (){} 可为对象定义一个迭代器