前言

单链表和双链表实现

单链表
  1. type LinkNode = {
  2. value: any;
  3. next: LinkNode;
  4. } | null;
  5. const loopIndex = Symbol();
  6. class LinkedList {
  7. nodes: LinkNode[] = [];
  8. isLoop: boolean = false;
  9. constructor(isLoop: boolean = false) {
  10. this.isLoop = isLoop;
  11. }
  12. get size(): number {
  13. return this.nodes.length;
  14. }
  15. get head(): LinkNode {
  16. return this.size ? this.nodes[0] : null;
  17. }
  18. get tail(): LinkNode {
  19. return this.size ? this.nodes[this.size - 1] : null;
  20. }
  21. [loopIndex](index: number): number {
  22. if (index < 0) return this.size + index;
  23. if (index > this.size) return this.size;
  24. return index;
  25. }
  26. insertAt(index: number, value: any) {
  27. index = this[loopIndex](index);
  28. const previous: LinkNode = this.nodes[index - 1] || null;
  29. const next: LinkNode = this.nodes[index] || null;
  30. const node: LinkNode = {
  31. value: value,
  32. next: next,
  33. };
  34. if (previous) previous.next = node;
  35. // 循环链表,首尾需要处理
  36. if (index === this.size && this.isLoop) node.next = this.head;
  37. if (index === 0 && this.isLoop) this.tail.next = node;
  38. this.nodes.splice(index, 0, node);
  39. }
  40. insertHead(value: any) {
  41. this.insertAt(0, value);
  42. }
  43. insertTail(value: any) {
  44. this.insertAt(this.size, value);
  45. }
  46. removeAt(index: number): LinkNode[] {
  47. index = this[loopIndex](index);
  48. let previous: LinkNode = this.nodes[index - 1] || null;
  49. let next: LinkNode = this.nodes[index + 1] || null;
  50. // 循环链表,首部处理
  51. if (this.isLoop && index === 0) {
  52. previous = this.tail;
  53. }
  54. // 循环链表,尾部处理
  55. if (this.isLoop && index === this.size - 1) {
  56. next = this.head;
  57. }
  58. if (previous) previous.next = next;
  59. return this.nodes.splice(index, 1);
  60. }
  61. getAt(index: number): LinkNode {
  62. index = this[loopIndex](index);
  63. return this.nodes[index];
  64. }
  65. clear() {
  66. this.nodes = [];
  67. }
  68. reverse() {
  69. return this.nodes.reduce((acc, { value }) => {
  70. return [{ value: value, next: acc[0] || null }, ...acc];
  71. }, []);
  72. }
  73. *[Symbol.iterator]() {
  74. yield* this.nodes;
  75. }
  76. }

双向链表
  1. type LinkNode = {
  2. value: any;
  3. next: LinkNode;
  4. previous: LinkNode;
  5. } | null;
  6. const loopIndex = Symbol();
  7. class DoubleLinkedList {
  8. nodes: LinkNode[] = [];
  9. isLoop: boolean = false;
  10. constructor(isLoop = false) {
  11. this.isLoop = isLoop;
  12. }
  13. get size(): number {
  14. return this.nodes.length;
  15. }
  16. get head(): LinkNode {
  17. return this.size ? this.nodes[0] : null;
  18. }
  19. get tail(): LinkNode {
  20. return this.size ? this.nodes[this.size - 1] : null;
  21. }
  22. [loopIndex](index: number): number {
  23. if (index < 0) return this.size + index;
  24. if (index > this.size) return this.size;
  25. return index;
  26. }
  27. insertAt(index: number, value: any) {
  28. index = this[loopIndex](index);
  29. const previous: LinkNode = this.nodes[index - 1] || null;
  30. const next: LinkNode = this.nodes[index] || null;
  31. const node: LinkNode = {
  32. value: value,
  33. previous: previous,
  34. next: next,
  35. };
  36. if (previous) previous.next = node;
  37. if (next) next.previous = node;
  38. // 循环链表,首尾需要处理
  39. if (this.isLoop && index === 0) {
  40. node.previous = this.tail;
  41. this.tail.next = node;
  42. }
  43. if (this.isLoop && index === this.size) {
  44. node.next = this.head;
  45. this.head.previous = node;
  46. }
  47. this.nodes.splice(index, 0, node);
  48. }
  49. insertHead(value: any) {
  50. this.insertAt(0, value);
  51. }
  52. insertTail(value: any) {
  53. this.insertAt(this.size, value);
  54. }
  55. removeAt(index: number): LinkNode[] {
  56. index = this[loopIndex](index);
  57. let previous: LinkNode = this.nodes[index - 1] || null;
  58. let next: LinkNode = this.nodes[index + 1] || null;
  59. // 循环列表,首部处理
  60. if (this.isLoop && index === 0) {
  61. previous = this.tail;
  62. }
  63. // 循环列表,尾部处理
  64. if (this.isLoop && index === this.size - 1) {
  65. next = this.head;
  66. }
  67. if (previous) previous.next = next;
  68. if (next) next.previous = previous;
  69. return this.nodes.splice(index, 1);
  70. }
  71. getAt(index: number): LinkNode {
  72. index = this[loopIndex](index);
  73. return this.nodes[index];
  74. }
  75. clear() {
  76. this.nodes = [];
  77. }
  78. reverse() {
  79. return this.nodes.reduce((acc, { value }) => {
  80. const next = acc[0] || null;
  81. const node = {
  82. value: value,
  83. next: next,
  84. previous: null,
  85. };
  86. if (next) next.previous = node;
  87. return [node, ...acc];
  88. }, []);
  89. }
  90. *[Symbol.iterator]() {
  91. yield* this.nodes;
  92. }
  93. }

反转链表
  1. function reverse(list){
  2. let cur = list.head;
  3. let previous = null;
  4. while(cur !== null){
  5. let temp = cur.next;
  6. cur.next = previous;
  7. previous = cur;
  8. cur = temp;
  9. }
  10. }