lgrthms
Version:
Algorithms and data structures for your JavaScript and TypeScript projects 🧑💻
209 lines (208 loc) • 5.86 kB
JavaScript
"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;