普通链表

    1. // 普通链表
    2. class linkList {
    3. constructor() {
    4. this.head = null;
    5. this.length = 0;
    6. this.findTail = () => {
    7. // 找到尾部的位置
    8. if(!this.head) {
    9. return null
    10. } else {
    11. let current = this.head;
    12. while(current.next) {
    13. current = current.next
    14. }
    15. return current;
    16. }
    17. };
    18. this.checkRange = (index) => {
    19. // 检查索引是否是合法的
    20. if(typeof index !== 'number' || index < 0 || index >= this.length) {
    21. throw new RangeError();
    22. }
    23. };
    24. this.findCurrent = (index) => {
    25. // 获取索引指定的位置
    26. let i = 0;
    27. let current = this.head;
    28. while(i !== index) {
    29. current = current.next;
    30. i++;
    31. }
    32. return current;
    33. }
    34. }
    35. // 获取item O(n)
    36. getItem(index) {
    37. // 检查index是否合法
    38. this.checkRange(index);
    39. const current = this.findCurrent(index);
    40. return current.value
    41. }
    42. // 设置item O(n)
    43. setItem(index, value) {
    44. // 检查index是否合法
    45. this.checkRange(index);
    46. const current = this.findCurrent(index);
    47. current.value = value;
    48. }
    49. // 添加数据 O(n)
    50. append(value) {
    51. let tail = this.findTail();
    52. if(!tail) {
    53. // 如果没有尾巴 说明只有一个头
    54. this.head = {
    55. value,
    56. next: null
    57. }
    58. } else {
    59. // 不是第一次添加
    60. let node = {value, next: null};
    61. tail.next = node;
    62. }
    63. this.length++;
    64. }
    65. // 插入 O(n)
    66. insert(index, value) {
    67. if(typeof index !== 'number' || index < 0 || index > this.length) {
    68. throw new RangeError();
    69. }
    70. // 需要创建一个新头
    71. if (index === 0) {
    72. const oldHead = this.head;
    73. this.head = { value, next: oldHead};
    74. } else {
    75. // 需要打散,获取插入指定位置的前一个
    76. const prev = this.findCurrent(index - 1);
    77. const oldCurrent = prev.next;
    78. // 创建新的数据 链接之前的
    79. const current = { value, next: oldCurrent};
    80. prev.next = current;
    81. }
    82. this.length++;
    83. }
    84. // 删除 O(n)
    85. delete(index) {
    86. this.checkRange(index);
    87. // 去掉老的头
    88. if(this.head) {
    89. if (index === 0) {
    90. this.head = this.head.next;
    91. } else {
    92. // 获取删除指定位置的前一个
    93. const prev = this.findCurrent(index - 1);
    94. if (!prev) return;
    95. const current = prev.next;
    96. if (!current) return;
    97. prev.next = current.next;
    98. }
    99. this.length--;
    100. }
    101. }
    102. // 查找 无序的 O(n)
    103. search(value) {
    104. let current = this.head;
    105. let i = 0;
    106. while(i < this.length) {
    107. if(!current) return -1;
    108. if(current.value === value) return i;
    109. current = current.next;
    110. i++;
    111. }
    112. // 如果没有找到 返回 -1
    113. return -1;
    114. }
    115. }
    116. let list = new linkList();
    117. list.append(1);
    118. list.append(3);
    119. list.append(5);
    120. list.append(8);
    121. list.append(10);
    122. console.log(list.search(5));
    123. console.log(list);

    双向链表
    优势:添加O(1)和 前删后删 O(1)

    1. // 一般链表效率都很差, 优化 双向链表
    2. class HTLinkList{
    3. constructor() {
    4. this.head = null;
    5. this.tail = null;
    6. this.length = 0;
    7. }
    8. // 算法复杂度 O(1)
    9. append(value) {
    10. // 如果有尾巴
    11. if(this.tail) {
    12. this.tail.next = {value, next: null, prev: this.tail};
    13. this.tail = this.tail.next;
    14. } else {
    15. // 如果没有 头和尾巴 都是一致的
    16. this.head = this.tail = {value, next: null, pre: null};
    17. }
    18. this.length++;
    19. }
    20. // 算法复杂度 O(1)
    21. pop() {
    22. let value;
    23. if(this.tail) {
    24. value = this.tail.value;
    25. // 如果前后都是 null
    26. if(!this.tail.next && !this.tail.prev) {
    27. this.length = 0;
    28. this.head = this.tail = null;
    29. } else {
    30. this.tail.prev.next = null;
    31. this.tail = this.tail.prev;
    32. }
    33. }
    34. this.length--;
    35. return value;
    36. }
    37. }
    38. let list = new HTLinkList();
    39. list.append(1);
    40. list.append(3);
    41. list.append(5);
    42. // 后删
    43. console.log(list.pop());
    44. console.log(list.pop());
    45. console.log(list);

    循环链表

    缓存链表