【若川视野 x 源码共读】第32期【队列链表】队列链表 67行

1,730 阅读2分钟

前言

hi,我是麦谷。今天恰好周六,我又来学习源码了:队列链表。从之前读过的一本书-学习JavaScript数据结构与算法(第3版)里得知,队列遵循的原则是先进先出(FIFO,也称为先来先服务),具体内容不细说,想要学习JavaScript算法的伙伴可以看看这本书。相信大多数伙伴对于链表这种数据结构并不陌生吧?链表在算法中具有非常重要的地位,比如面试过程中经常被问到原型链……

队列链表

在我学习源码的过程中往往是带着自己的疑惑去学习的,当自己的疑惑解决完了,就大概理解源码的内容了。

什么是队列链表?
队列链表和队列有什么关系?

先贴上源码:

/*
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)且元素节点是节点的数据结构。

队列链表和队列有什么关系?

链表上的节点可以存储多个属性,队列链表的每个元素都是一个链表节点。