From 25b65225723f2e3591907bcd203b923d0173ad4b Mon Sep 17 00:00:00 2001 From: Smig <89040888+smiggiddy@users.noreply.github.com> Date: Sat, 10 Feb 2024 12:16:48 -0500 Subject: [PATCH] Csci (#14) * feat: project bts * feat: balanced binary tree project --- csci/projectBTS.js | 303 +++++++++++++++++++++++++++++++++++++++++ csci/projectHashSet.js | 28 ++-- 2 files changed, 318 insertions(+), 13 deletions(-) create mode 100644 csci/projectBTS.js diff --git a/csci/projectBTS.js b/csci/projectBTS.js new file mode 100644 index 0000000..3025aea --- /dev/null +++ b/csci/projectBTS.js @@ -0,0 +1,303 @@ +class Node { + constructor(d = null) { + this.data = d; + this.left = null; + this.right = null; + } +} + +class balancedBinaryTree { + constructor(arr = []) { + this.sort(arr); + this.set(); + this.tree = this.buildTree(this.arr, 0, this.arr.length - 1); + } + buildTree(arr, start, end) { + if (start > end) return null; + + const mid = Math.round((start + end) / 2); + let node = new Node(arr[mid]); + + node.left = this.buildTree(arr, start, mid - 1); + node.right = this.buildTree(arr, mid + 1, end); + + return node; + } + + sort(arr) { + this.arr = arr.sort((a, b) => a - b); + } + + set() { + let tempArr = []; + + for (let i = 0; i < this.arr.length; i++) { + if (!tempArr.includes(this.arr[i])) { + tempArr.push(this.arr[i]); + } + } + this.arr = tempArr; + } + + insert(value, node = this.tree) { + if (node == null) { + node = new Node(value); + return node; + } + + // don't insert duplicates + if (value === node.data) return node; + + if (value < node.data) { + node.left = this.insert(value, node.left); + } else { + node.right = this.insert(value, node.right); + } + return node; + } + + delete(value, node = this.tree) { + if (node == null) return node; + + if (node.data == value) { + if (node.left && node.right) { + let temp = node.right; + node = node.left; + node.right = temp; + } else if (node.left || node.right) { + node = node.left ? node.left : node.right; + } else { + node = null; + } + return node; + } + + if (value < node.data) { + node.left = this.delete(value, node.left); + } else { + node.right = this.delete(value, node.right); + } + + return node; + } + + find(value, node = this.tree) { + let found = null; + + function searchTree(n) { + if (n == null) return null; + if (n.data === value) { + found = n; + return n; + } + n.left = searchTree(n.left); + n.right = searchTree(n.right); + return n; + } + searchTree(node); + return found; + } + + prettyPrint(node, prefix = '', isLeft = true) { + if (node === null) { + return; + } + if (node.right !== null) { + this.prettyPrint( + node.right, + `${prefix}${isLeft ? '│ ' : ' '}`, + false, + ); + } + console.log(`${prefix}${isLeft ? '└── ' : '┌── '}${node.data}`); + if (node.left !== null) { + this.prettyPrint( + node.left, + `${prefix}${isLeft ? ' ' : '│ '}`, + true, + ); + } + } + levelOrder(callback = null) { + const queue = []; + const values = []; + let node = this.tree; + + function processQueue(arr) { + while (arr.length > 0) { + let item = arr.shift(); + if (item) { + callback ? callback(item) : values.push(item.data); + } + if (item.left) queue.push(item.left); + if (item.right) queue.push(item.right); + } + } + + function proccessQueueRecursively(level) { + function _helper(n, level) { + if (n == null) return; + + if (level === 1) { + callback ? callback(n) : values.push(n.data); + } else { + _helper(n.left, level - 1); + _helper(n.right, level - 1); + } + } + + for (let i = 1; i <= level; i++) { + _helper(node, i); + } + } + + if (!node) { + console.log('Need a tree with some values dude'); + return; + } + queue.push(node); + + // get tree height for recursion + // let h = this.height(node); + + processQueue(queue); + // proccessQueueRecursively(h); + + return values; + } + + inOrder(callback = null) { + const tree = this.tree; + const values = []; + + function inOrderHelper(n) { + if (tree == null) { + return; + } + if (n.left) inOrderHelper(n.left); + callback ? callback(n.data) : values.push(n.data); + if (n.right) inOrderHelper(n.right); + } + inOrderHelper(tree); + return values; + } + + preOrder(callback = null) { + const tree = this.tree; + const values = []; + + function preOrderHelper(n) { + if (tree == null) { + return; + } + callback ? callback(n.data) : values.push(n.data); + if (n.left) preOrderHelper(n.left); + if (n.right) preOrderHelper(n.right); + } + preOrderHelper(tree); + return values; + } + + postOrder(callback = null) { + const tree = this.tree; + const values = []; + + function postOrderHelper(n) { + if (tree == null) { + return; + } + if (n.left) postOrderHelper(n.left); + if (n.right) postOrderHelper(n.right); + callback ? callback(n.data) : values.push(n.data); + } + postOrderHelper(tree); + return values; + } + + height(node) { + function heightHelper(n) { + if (n == null) return 0; + let leftHeight = heightHelper(n.left); + let rightHeight = heightHelper(n.right); + return Math.max(leftHeight, rightHeight) + 1; + } + return heightHelper(node) - 1; + } + + depth(node) { + let treeHeight = this.height(this.tree); + let nodeHeight = this.height(node); + + return treeHeight - nodeHeight; + } + + isBalanced() { + let self = this; + let isBalanced = true; + + function balanceHelper(node) { + let left; + let right; + + if (node.left) left = self.find(node.left.data); + if (node.right) right = self.find(node.right.data); + + let leftHeight = self.height(left); + let rightHeight = self.height(right); + + return Math.abs(leftHeight - rightHeight) <= 1; + } + + this.levelOrder((n) => { + if (!balanceHelper(n)) isBalanced = false; + }); + + return isBalanced; + } + + rebalance() { + let tree = this.inOrder(); + this.tree = this.buildTree(tree, 0, tree.length - 1); + } +} + +function main() { + let getRandomNumber = (max) => Math.floor(Math.random() * max); + let buildArray = () => { + let arr = []; + for (let i = 0; i < 100; i++) { + arr.push(getRandomNumber(100)); + } + return arr; + }; + let unbalanceTree = (bst) => { + for (let i = 0; i < 50; i++) { + bst.insert(getRandomNumber(200)); + } + }; + + console.log('WELCOME TO THE BINARY TREE STUFF'); + console.log('BUILDING TREE WITH 100 RANDOM NUMBERS'); + let testArr = buildArray(); + let tree = new balancedBinaryTree(testArr); + tree.prettyPrint(tree.tree); + console.log('UNBALANCING THIS JOINT'); + unbalanceTree(tree); + tree.prettyPrint(tree.tree); + console.log('LET ME SEE IF THAT WOKRED'); + console.log(`IS THE TREE BALANCED G? ${tree.isBalanced()}`); + tree.rebalance(); + console.log('LETS FIX THAT BUDDY'); + tree.prettyPrint(tree.tree); + console.log('LETS DO THE TRAVERSALS NOW'); + console.log('LEVEL ORDER'); + console.log(tree.levelOrder()); + console.log('PRE ORDER'); + console.log(tree.preOrder()); + console.log('IN ORDER'); + console.log(tree.inOrder()); + console.log('POST ORDER'); + console.log(tree.postOrder()); +} + +main(); diff --git a/csci/projectHashSet.js b/csci/projectHashSet.js index 7316e07..149161d 100644 --- a/csci/projectHashSet.js +++ b/csci/projectHashSet.js @@ -112,16 +112,18 @@ class HashSet { } } -const _set = new HashSet(); -_set.set('test'); -_set.set('test'); -_set.set('hello'); -_set.set('deeeez'); -_set.set('deeez'); -_set.set('deez'); -_set.set('dez'); -_set.set('trueskii'); -_set.set('mike'); -console.log(_set.keys()); -_set.remove('test'); -console.log(_set.buckets); +export { HashSet }; + +// const _set = new HashSet(); +// _set.set('test'); +// _set.set('test'); +// _set.set('hello'); +// _set.set('deeeez'); +// _set.set('deeez'); +// _set.set('deez'); +// _set.set('dez'); +// _set.set('trueskii'); +// _set.set('mike'); +// console.log(_set.keys()); +// _set.remove('test'); +// console.log(_set.buckets);