前言
单链表和双链表实现
单链表
type LinkNode = { value: any; next: LinkNode;} | null;const loopIndex = Symbol();class LinkedList { nodes: LinkNode[] = []; isLoop: boolean = false; constructor(isLoop: boolean = false) { this.isLoop = isLoop; } get size(): number { return this.nodes.length; } get head(): LinkNode { return this.size ? this.nodes[0] : null; } get tail(): LinkNode { return this.size ? this.nodes[this.size - 1] : null; } [loopIndex](index: number): number { if (index < 0) return this.size + index; if (index > this.size) return this.size; return index; } insertAt(index: number, value: any) { index = this[loopIndex](index); const previous: LinkNode = this.nodes[index - 1] || null; const next: LinkNode = this.nodes[index] || null; const node: LinkNode = { value: value, next: next, }; if (previous) previous.next = node; // 循环链表,首尾需要处理 if (index === this.size && this.isLoop) node.next = this.head; if (index === 0 && this.isLoop) this.tail.next = node; this.nodes.splice(index, 0, node); } insertHead(value: any) { this.insertAt(0, value); } insertTail(value: any) { this.insertAt(this.size, value); } removeAt(index: number): LinkNode[] { index = this[loopIndex](index); let previous: LinkNode = this.nodes[index - 1] || null; let next: LinkNode = this.nodes[index + 1] || null; // 循环链表,首部处理 if (this.isLoop && index === 0) { previous = this.tail; } // 循环链表,尾部处理 if (this.isLoop && index === this.size - 1) { next = this.head; } if (previous) previous.next = next; return this.nodes.splice(index, 1); } getAt(index: number): LinkNode { index = this[loopIndex](index); return this.nodes[index]; } clear() { this.nodes = []; } reverse() { return this.nodes.reduce((acc, { value }) => { return [{ value: value, next: acc[0] || null }, ...acc]; }, []); } *[Symbol.iterator]() { yield* this.nodes; }}
双向链表
type LinkNode = { value: any; next: LinkNode; previous: LinkNode;} | null;const loopIndex = Symbol();class DoubleLinkedList { nodes: LinkNode[] = []; isLoop: boolean = false; constructor(isLoop = false) { this.isLoop = isLoop; } get size(): number { return this.nodes.length; } get head(): LinkNode { return this.size ? this.nodes[0] : null; } get tail(): LinkNode { return this.size ? this.nodes[this.size - 1] : null; } [loopIndex](index: number): number { if (index < 0) return this.size + index; if (index > this.size) return this.size; return index; } insertAt(index: number, value: any) { index = this[loopIndex](index); const previous: LinkNode = this.nodes[index - 1] || null; const next: LinkNode = this.nodes[index] || null; const node: LinkNode = { value: value, previous: previous, next: next, }; if (previous) previous.next = node; if (next) next.previous = node; // 循环链表,首尾需要处理 if (this.isLoop && index === 0) { node.previous = this.tail; this.tail.next = node; } if (this.isLoop && index === this.size) { node.next = this.head; this.head.previous = node; } this.nodes.splice(index, 0, node); } insertHead(value: any) { this.insertAt(0, value); } insertTail(value: any) { this.insertAt(this.size, value); } removeAt(index: number): LinkNode[] { index = this[loopIndex](index); let previous: LinkNode = this.nodes[index - 1] || null; let next: LinkNode = this.nodes[index + 1] || null; // 循环列表,首部处理 if (this.isLoop && index === 0) { previous = this.tail; } // 循环列表,尾部处理 if (this.isLoop && index === this.size - 1) { next = this.head; } if (previous) previous.next = next; if (next) next.previous = previous; return this.nodes.splice(index, 1); } getAt(index: number): LinkNode { index = this[loopIndex](index); return this.nodes[index]; } clear() { this.nodes = []; } reverse() { return this.nodes.reduce((acc, { value }) => { const next = acc[0] || null; const node = { value: value, next: next, previous: null, }; if (next) next.previous = node; return [node, ...acc]; }, []); } *[Symbol.iterator]() { yield* this.nodes; }}
反转链表
function reverse(list){ let cur = list.head; let previous = null; while(cur !== null){ let temp = cur.next; cur.next = previous; previous = cur; cur = temp; }}