JavaScript数据结构yocto queue队列链表代码分析

作者:半夏时间:2026-10-26 07:52:17浏览:644

本文深入分析JavaScript轻量级队列库yocto-queue的源码实现。通过解析链表结构、入队出队逻辑及Symbol.iterator迭代器定义,展示其相比原生Array.push和shift在大数据量操作下的性能优势。结合VS Code远程开发环境,详细解读核心代码片段,帮助开发者理解高效队列与迭代器的构建细节。

前言

Yocto-queue 是一种专门设计用于高效存储和检索数据的数据结构。它属于队列类型,本质上是一个元素集合,其核心特性在于元素从一端添加,并从另一端移除。

该数据结构专为处理大规模数组数据而设计。当应用场景涉及大量 Array.push 和 Array.shift 操作时,Yocto-queue 能展现出比原生数组更优越的性能表现。

项目仓库地址:sindresorhus/yocto-queue: Tiny queue data structure (github.com)

准备工作

虽然在浏览器中直接调试代码十分便捷,但为了体现开发的专业性,我们推荐使用 Github Workspace 进行本地 VS Code 开发。

首先打开 yocto-queue 仓库,创建一个 Github Codespace。返回 Github 首页,在导航栏点击 Workspace,找到刚创建的项目并选择使用 VS Code 打开,具体操作如图:

前言

VS Code 会提示安装 Github Workspace 插件。该插件功能类似于 Remote SSH,旨在为远程服务器上的开发提供支持。这样做的好处包括跨平台兼容性、多端协同操作以及统一开发环境。

分析代码

源码如下:

/*
How it works:
`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.
*/
class Node {
	value;
	next;
	constructor(value) {
		this.value = value;
	}
}
export default 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() {
		const current = this.#head;
		if (!current) {
			return;
		}
		this.#head = this.#head.next;
		this.#size--;
		return current.value;
	}
	clear() {
		this.#head = undefined;
		this.#tail = undefined;
		this.#size = 0;
	}
	get size() {
		return this.#size;
	}
	* [Symbol.iterator]() {
		let current = this.#head;
		while (current) {
			yield current.value;
			current = current.next;
		}
	}
}

队列

队列是一种遵循先进先出(FIFO)原则的数据结构,具备以下核心特点:

  • 新元素始终被添加到队列的末尾。
  • 队列中已存在的元素保持其原有的先后顺序不变。
  • 在任何时刻,只能从队列的起始端(头部)移除元素。

入队

	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++;
	}

该方法用于向队列中添加值,接收一个值作为参数,并据此创建一个新的 Node 对象。

如果队列中已存在 head 和 tail 节点,新节点将被追加到队列末尾。具体操作是将 tail 节点的 next 属性指向新节点,并将 tail 属性更新为新节点。

若队列为空,新节点将同时成为 head 和 tail 节点。最后,队列的 size 属性会增加,以反映新添加节点后的队列大小。

出队

该方法用于从队列中移除顶部节点的值,并将其返回。

	dequeue() {
		const current = this.#head;
		if (!current) {
			return;
		}
		this.#head = this.#head.next;
		this.#size--;
		return current.value;
	}

实现时,首先检查 head 属性是否为空以判断队列状态。若队列为空,方法返回 null;若不为空,则将 head 属性更新为队列中的下一个节点,并减少 size 属性以反映移除操作。最后,返回原 head 节点的值。

迭代器

此功能允许 yocto-queue 在 for...of 循环中被直接使用。

	* [Symbol.iterator]() {
		let current = this.#head;
		while (current) {
			yield current.value;
			current = current.next;
		}
	}

通过定义 Symbol.iterator 符号,为队列提供了自定义迭代器。迭代器初始化时将 current 变量设为队列的 head 属性。随后进入循环,只要 current 不为 null 便持续执行。每次迭代中,使用 yield 关键字输出 current 节点的 value 属性,并将 current 更新为下一个节点。这使得 for...of 循环能够遍历队列中的所有值。

总结

通过阅读 yocto-queue 的源码,我们掌握了队列的具体实现方式以及迭代器的应用技巧。对比数组与队列两种数据结构的使用场景:数组在查询方面速度较快,但插入操作较慢;而队列则在插入操作上更快,但查询速度相对较慢。

以上就是JavaScript数据结构yocto queue队列链表代码分析的详细内容,更多关于JavaScript yocto queue队列链表的资料请关注本站其它相关文章!

作者最新文章