UNPKG

lgrthms

Version:

Algorithms and data structures for your JavaScript and TypeScript projects 🧑‍💻

156 lines (155 loc) 4.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SinglyLinkedList = void 0; class Node { constructor(value) { this.value = value; this.next = null; } } class SinglyLinkedList { constructor() { this._head = null; this._length = 0; } get head() { return this._head; } get length() { return this._length; } // O(n) time | O(1) space get(index) { const node = this.getNode(index); return node ? node.value : undefined; } // O(n) time | O(1) space getNode(index) { const lastIndex = this._length - 1; if (index < 0 || index > lastIndex) { return; } let current = this._head; let currentIndex = 0; while (currentIndex < index) { current = current.next; currentIndex++; } return current || undefined; } // O(n) time | O(1) space find(predicate) { const node = this.findNode(predicate); return node ? node.value : undefined; } // O(n) time | O(1) space findNode(predicate) { let current = this._head; while (current) { if (predicate(current.value)) { return current; } current = current.next; } } // Best: O(1) time | O(1) space // Average: O(n) time | O(1) space insert(value, index) { const lastIndex = this._length - 1; if (index === undefined) { index = lastIndex + 1; } if (index < 0 || index > lastIndex + 1) { throw new Error('Cannot insert value, given index is out of bounds'); } if (index === 0) { return this.setHead(value); } const insertAfterIndex = index - 1; const insertAfterNode = this.getNode(insertAfterIndex); return this.insertAfter(value, insertAfterNode); } // O(1) time | O(1) space insertAfter(value, node) { const nodeToInsert = new Node(value); nodeToInsert.next = node.next; node.next = nodeToInsert; this._length++; return nodeToInsert; } // O(n) time | O(1) space removeAtIndex(index) { const lastIndex = this._length - 1; if (index < 0 || index > lastIndex) { return; } let current = this._head; let previous = null; let currentIndex = 0; while (currentIndex < index) { previous = current; current = current.next; currentIndex++; } return this.remove(current, previous); } // O(n) time | O(1) space removeWithValue(predicate) { let current = this._head; let previous = null; while (current) { if (predicate(current.value)) { this.remove(current, previous); } else { previous = current; } current = current.next; } } // O(n) time | O(1) space removeNode(node) { if (!node) { return; } let current = this._head; let previous = null; while (current) { if (current === node) { return this.remove(current, previous); } previous = current; current = current.next; } } // O(n) time | O(1) space forEach(callbackfn) { let current = this._head; while (current) { callbackfn(current.value); current = current.next; } } // O(1) time | O(1) space setHead(value) { const node = new Node(value); node.next = this._head; this._head = node; this._length++; return this._head; } // O(1) time | O(1) space remove(node, previous) { if (node === this._head) { this._head = node.next; } else if (previous) { previous.next = node.next; } else { throw new Error('Cannot remove node, make sure to pass valid parameters'); } this._length--; } } exports.SinglyLinkedList = SinglyLinkedList;