UNPKG

lgrthms

Version:

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

209 lines (208 loc) 5.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BinaryTree = void 0; const Queue_1 = require("./Queue"); class BinaryTree { constructor(value) { this._parent = null; this._left = null; this._right = null; this._size = 1; this.value = value; } get size() { return this._size; } // O(1) time | O(1) space set parent(tree) { this._parent = tree; } get parent() { return this._parent; } // O(log(n)) time | O(1) space set left(tree) { var _a; const currentSize = ((_a = this._left) === null || _a === void 0 ? void 0 : _a.size) || 0; const sizeToAdd = tree.size - currentSize; tree.parent = this; this._left = tree; this._size += sizeToAdd; let current = this.parent; while (current) { current._size += sizeToAdd; current = current.parent; } } get left() { return this._left; } // O(log(n)) time | O(1) space set right(tree) { var _a; const currentSize = ((_a = this._right) === null || _a === void 0 ? void 0 : _a.size) || 0; const sizeToAdd = tree.size - currentSize; tree.parent = this; this._right = tree; this._size += sizeToAdd; let current = this.parent; while (current) { current._size += sizeToAdd; current = current.parent; } } get right() { return this._right; } // O(n) time | O(n) space insert(value) { const tree = new BinaryTree(value); const queue = new Queue_1.Queue(); queue.enqueue(this); while (queue.size > 0) { const current = queue.dequeue(); if (!current.left) { tree.parent = current; current.left = tree; break; } else { queue.enqueue(current.left); } if (!current.right) { tree.parent = current; current.right = tree; break; } else { queue.enqueue(current.right); } } return tree; } // O(n) time | O(n) space remove(tree) { let deepest = this; let isFound = false; const queue = new Queue_1.Queue(); queue.enqueue(this); while (queue.size > 0) { const current = queue.dequeue(); if (!current) { continue; } if (!isFound) { isFound = tree === current; } deepest = current; queue.enqueue(current._left); queue.enqueue(current._right); } if (!isFound) { return; } if (deepest.parent === null) { return; } else if (deepest.parent._left === deepest) { deepest.parent._left = null; } else { deepest.parent._right = null; } tree.value = deepest.value; let current = deepest.parent; while (current) { current._size--; current = current.parent; } deepest._parent = null; deepest._left = null; deepest._right = null; deepest._size = 1; } // O(n^2) time | O(n) space removeWithValue(predicate) { const trees = []; const queue = new Queue_1.Queue(); queue.enqueue(this); while (queue.size > 0) { const current = queue.dequeue(); if (!current) { continue; } trees.push(current); queue.enqueue(current._left); queue.enqueue(current._right); } for (let i = trees.length - 1; i >= 0; i--) { const tree = trees[i]; if (predicate(tree.value)) { this.remove(tree); } } } // O(n) time | O(h) space dfs(predicate) { if (predicate(this.value)) { return this; } return (this.left ? this.left.dfs(predicate) : null) || (this.right ? this.right.dfs(predicate) : null); } // O(n) time | O(h) space deepFirstSearch(predicate) { return this.dfs(predicate); } // O(n) time | O(n) space bfs(predicate) { const queue = new Queue_1.Queue(); queue.enqueue(this); while (queue.size > 0) { const current = queue.dequeue(); if (!current) { continue; } if (predicate(current.value)) { return current; } queue.enqueue(current.left); queue.enqueue(current.right); } return null; } // O(n) time | O(n) space breadthFirstSearch(predicate) { return this.bfs(predicate); } // O(n) time | O(h) space traverseInOrder(callbackfn) { if (this.left) { this.left.traverseInOrder(callbackfn); } callbackfn(this.value); if (this.right) { this.right.traverseInOrder(callbackfn); } } // O(n) time | O(h) space traversePreOrder(callbackfn) { callbackfn(this.value); if (this.left) { this.left.traversePreOrder(callbackfn); } if (this.right) { this.right.traversePreOrder(callbackfn); } } // O(n) time | O(h) space traversePostOrder(callbackfn) { if (this.left) { this.left.traversePostOrder(callbackfn); } if (this.right) { this.right.traversePostOrder(callbackfn); } callbackfn(this.value); } } exports.BinaryTree = BinaryTree;