JavaScript 数据结构 - 链表

79 阅读2分钟

JavaScript 数据结构 - 链表

[定义]

链表是一种线性数据结构,它表示元素的集合,其中每个元素都指向下一个元素。链表中的第一个元素是 head,最后一个元素是 tail。

image.png

链表数据结构的每个元素必须具有以下属性:

  • value:元素的值
  • next:指向链表中下一个元素的指针(如果没有)null

链表数据结构的主要属性是:

  • size:链表中的元素数
  • head:链表中的第一个元素
  • tail:链表中的最后一个元素

链表数据结构的主要操作是:

  • insertAt:在特定索引处插入元素
  • removeAt:删除特定索引处的元素
  • getAt:检索特定索引处的元素
  • clear:清空链表
  • reverse:反转链表中元素的顺序

[实现]


class LinkedList {
  constructor() {
    this.nodes = [];
  }

  get size() {
    return this.nodes.length;
  }

  get head() {
    return this.size ? this.nodes[0] : null;
  }

  get tail() {
    return this.size ? this.nodes[this.size - 1] : null;
  }

  insertAt(index, value) {
    const previousNode = this.nodes[index - 1] || null;
    const nextNode = this.nodes[index] || null;
    const node = { value, next: nextNode };

    if (previousNode) previousNode.next = node;
    this.nodes.splice(index, 0, node);
  }

  insertFirst(value) {
    this.insertAt(0, value);
  }

  insertLast(value) {
    this.insertAt(this.size, value);
  }

  getAt(index) {
    return this.nodes[index];
  }

  removeAt(index) {
    const previousNode = this.nodes[index - 1];
    const nextNode = this.nodes[index + 1] || null;

    if (previousNode) previousNode.next = nextNode;

    return this.nodes.splice(index, 1);
  }

  clear() {
    this.nodes = [];
  }

  reverse() {
    this.nodes = this.nodes.reduce(
      (acc, { value }) => [{ value, next: acc[0] || null }, ...acc],
      []
    );
  }

  *[Symbol.iterator]() {
    yield* this.nodes;
  }
}
  • 创建一个 with a 为每个实例初始化一个空数组 。class``constructor``nodes
  • 定义一个 getter,它返回使用sizeArray.prototype.length返回数组中的元素数。nodes
  • 定义一个 getter,它返回数组的第一个元素,或者如果为空。head``nodes``null
  • 定义一个 getter,它返回数组的最后一个元素,或者如果为空。tail``nodes``null
  • 定义一个方法,该方法使用insertAt()Array.prototype.splice()在数组中添加新对象,更新前一个元素的键。nodes``next
  • 定义两个便捷的方法,分别使用该方法在数组的开头或结尾插入新元素。insertFirst()``insertLast()``insertAt()``nodes
  • 定义一个方法,该方法检索给定 .getAt()``index
  • 定义一个方法,该方法使用removeAt()Array.prototype.splice()要删除数组中的对象,请更新前一个元素的键。nodes``next
  • 定义一个清空数组的方法。clear()``nodes
  • 定义一个方法,该方法使用reverse()Array.prototype.reduce()和展开运算符 (...) 反转数组的顺序,并相应地更新每个元素的键。nodes``next
  • 定义 的生成器方法Symbol.iterator,它使用nodesyield*语法。
const list = new LinkedList();

list.insertFirst(1);
list.insertFirst(2);
list.insertFirst(3);
list.insertLast(4);
list.insertAt(3, 5);

list.size;                      // 5
list.head.value;                // 3
list.head.next.value;           // 2
list.tail.value;                // 4
[...list.map(e => e.value)];    // [3, 2, 1, 5, 4]

list.removeAt(1);               // 2
list.getAt(1).value;            // 1
list.head.next.value;           // 1
[...list.map(e => e.value)];    // [3, 1, 5, 4]

list.reverse();
[...list.map(e => e.value)];    // [4, 5, 1, 3]

list.clear();
list.size;                      // 0