单链表

  1. // 定义单个节点
  2. class Node {
  3. constructor(el) {
  4. this.el = el;
  5. this.next = null;
  6. }
  7. }
  8. class LinkedList {
  9. constructor() {
  10. this.head = new Node('head');
  11. }
  12. // 用于查找
  13. find(item) {
  14. let node = this.head;
  15. while (node !== null && node.el !== item) {
  16. node = node.next;
  17. }
  18. return node;
  19. }
  20. findPrev() {
  21. let node = this.head;
  22. while (node.next !== null && node.next.el !== item) {
  23. node = node.next;
  24. }
  25. return node;
  26. }
  27. // 插入节点
  28. insert(el, item) {
  29. const newNode = new Node(el);
  30. const currentNode = this.find(item);
  31. newNode.next = currentNode.next;
  32. currentNode.next = newNode;
  33. }
  34. // 删除节点
  35. remove(item) {
  36. const prevNode = this.findPrev(item); // 先找到待删除的元素
  37. if (prevNode.next !== null) {
  38. // 指向下一个元素,这行代码很关键
  39. prevNode.next = prevNode.next.next;
  40. }
  41. }
  42. }

双向链表

Node

和单链表类似,在原有的 Node 基础上,增加一个 prev 指针。

  1. class Node {
  2. constructor(el) {
  3. this.el = el;
  4. this.prev = null;
  5. this.next = null;
  6. }
  7. }

查找

双向链表的查找和单链表是一模一样的

插入

js实现链表(单链表、双向链表、跳表) - 图1

  1. function insert(el, item) {
  2. const newNode = new Node(el);
  3. const currentNode = this.find(item);
  4. // 新节点的下一个值指向当前节点的下一个值
  5. newNode.next = currentNode.next;
  6. // 新节点的前一个值指向当前节点
  7. nextNode.prev = currentNode;
  8. // 当前节点的下一个值指向新节点
  9. currentNode.next = newNode;
  10. // 当前节点的下一个节点的前一个节点指向新的值
  11. currentNode.next.prev = newNode;
  12. }

删除

js实现链表(单链表、双向链表、跳表) - 图2

  1. function remove(item) {
  2. const node = this.find(item);
  3. // 当前节点的前一个值的下一个值指向当前节点的下一个值 (相当于把当前节点略过了)
  4. node.prev.next = node.next;
  5. // 当前节点的下一个值的前一个值指向当前节点的前一个值
  6. node.next.prev = node.prev;
  7. 当前节点的下一个值和前一个值指向null 完成删除
  8. // node.next = null;
  9. node.prev = null;
  10. }

跳表

参考

https://101.zoo.team/lian-biao