JavaScript 链表

(成功的唯一秘诀——坚持最终一分钟。——柏拉图)

在这里插入图片描述

链表

众所周知,数组的查询比链表快,但插入比链表慢。

这是因为链表是一种动态的数据结构,不同于数组的是,链表分配内存空间的灵活性,它不会像数组一样被分配一块连续的内存。当你想在数组的任意位置,插入一个新值的时候,必须对数组中的各个元素进行相应的位置移动才能达到目标,开销显然是很大的。然而链表的灵活性在于它的每个元素节点分为两部分,一部分是存储元素本身,另一部分是指向下一个节点元素的引用,也可以称为指针,当你要插入数据时,把上一个节点的向下指针指向新数据节点,新数据节点的向下指针指向原有数据。但是链表不像数组那样可以直接通过索引立刻定位,只能通过遍历。

JavaScript实现链表

function LinkedList() {
    
    
  this.length = 0;
  this.head = null;
}

function Node(val) {
    
    
  this.val = val;
  this.next = null;
}

LinkedList.prototype.getNodeByIndex = function (idx) {
    
    
  if (typeof idx !== "number") throw new Error("id is not valid");
  if (idx < 0 || idx >= this.length) return null;
  let cur = this.head;
  while (idx--) {
    
    
    cur = cur.next;
  }
  return cur;
};

LinkedList.prototype.append = function (val) {
    
    
  let node = new Node(val);
  if (this.length === 0) {
    
    
    this.head = node;
  } else {
    
    
    this.getNodeByIndex(this.length - 1).next = node;
  }
  this.length++;
};

LinkedList.prototype.insert = function (pos, val) {
    
    
  if (pos < 0 || pos >= this.length) return false;
  let node = new Node(val);
  if (pos === 0) {
    
    
    node.next = this.head;
    this.head = node;
  } else {
    
    
    let prev = this.getNodeByIndex(pos - 1);
    node.next = prev.next;
    prev.next = node;
  }
  this.length++;
  return true;
};

LinkedList.prototype.removeAt = function (pos) {
    
    
  if (pos < 0 || pos >= this.length) return false;
  if (pos === 0) {
    
    
    this.head = this.head.next;
  } else {
    
    
    let prev = this.getNodeByIndex(pos - 1);
    prev.next = prev.next.next;
  }
  this.length--;
  return true;
};

为什么JavaScript没有提供内置的链表api?

目前并没有权威的机构来说明这个问题,但从js的发展史来看,也可以得出一些原因

  1. 使用链表的主要目的是提高性能,当有大量记录并且频繁更改它们时,链表有助于优化它。但对于大多数 JavaScript 应用程序而言,情况可能并非如此。对于 JavaScript,数组几乎可以做到这一点
  2. 大多数框架都依赖于数组,无论是 React、Vue 等。
  3. 当你需要对一个巨大的列表进行大量修改时,使用链表是合理的——尤其是在列表末尾以外的地方添加或删除项目时,这种情况在 JavaScript/前端中很少见。
  4. 在过去,js主要针对的是web端开发,而在web端的性能瓶颈在io,所以对于部分性能方面的api并没有提供
  5. 最后但并非最不重要的一点是,JavaScript 对数组有很好的支持,但您必须编写自己的实现代码或使用一些提供链表实现的库。
  6. 其他原因

链表的种类和区别

  1. 单链表
    每个节点只有一个指针域,指向下一个节点。单链表的插入和删除操作比较简单,但是查询慢。
  2. 双链表
    每个节点有两个指针域,分别指向前一个节点和后一个节点。双链表可以方便地实现双向遍历,但是占用空间比较大。
  3. 循环链表
    尾节点的指针域指向链表的头节点。循环链表比单链表和双链表的查询效率更高,但是在插入和删除操作时需要注意维护链表的结构。

猜你喜欢

转载自blog.csdn.net/qq_42427109/article/details/130622987