diff --git a/src/_DataStructures_/Trees/BinaryTree/index.js b/src/_DataStructures_/Trees/BinaryTree/index.js index f30999ad..7cb032c4 100644 --- a/src/_DataStructures_/Trees/BinaryTree/index.js +++ b/src/_DataStructures_/Trees/BinaryTree/index.js @@ -3,14 +3,14 @@ const Node = require('./Node'); class BinaryTree { constructor(arr) { if (!Array.isArray(arr) || !arr.length) { - throw new Error('Invalid argument to create a Binary Tre'); + throw new Error('Invalid argument to create a Binary Tree'); } this.root = this.createBinaryTree((this.root = null), arr, 0); } // eslint-disable-next-line class-methods-use-this createBinaryTree(root, arr, i) { - if (i < arr.length) { + if (i < arr.length && arr[i]) { // eslint-disable-next-line no-param-reassign root = new Node(arr[i]); // eslint-disable-next-line no-param-reassign diff --git a/src/_Problems_/binary-tree-to-binary-search-tree/binary-tree-to-binary-search-tree.test.js b/src/_Problems_/binary-tree-to-binary-search-tree/binary-tree-to-binary-search-tree.test.js new file mode 100644 index 00000000..95913a7e --- /dev/null +++ b/src/_Problems_/binary-tree-to-binary-search-tree/binary-tree-to-binary-search-tree.test.js @@ -0,0 +1,15 @@ +const { binaryTreeToBST, storeInorder } = require('.'); +const BinaryTree = require('../../_DataStructures_/Trees/BinaryTree'); + +describe('Binary tree to binary search tree', () => { + let tree; + + describe('Create Binary Tree', () => { + tree = new BinaryTree([10, 30, 15, 20, null, null, 5]); + }); + + it('Should converted binary tree to binary search tree', () => { + const bTree = binaryTreeToBST(tree); + expect(storeInorder(bTree)).toEqual([5, 10, 15, 20, 30]); + }); +}); diff --git a/src/_Problems_/binary-tree-to-binary-search-tree/index.js b/src/_Problems_/binary-tree-to-binary-search-tree/index.js new file mode 100644 index 00000000..1a56c5bd --- /dev/null +++ b/src/_Problems_/binary-tree-to-binary-search-tree/index.js @@ -0,0 +1,78 @@ +/** + * Given a Binary Tree, convert it to a Binary Search Tree. + * The conversion must be done in such a way that keeps the original structure of Binary Tree. + * Example 1 +Input: + 10 + / \ + 2 7 + / \ + 8 4 +Output: + 8 + / \ + 4 10 + / \ + 2 7 + */ + +const Node = require('../../_DataStructures_/Trees/BinaryTree/Node'); +// Helper function to store inorder traversal of a binary tree +function storeInorder(root) { + /** left - root - right */ + if (root === null) return []; + + // First store the left subtree + let arr = []; + const left = storeInorder(root.leftChild); + arr = [...left, ...arr]; + + // Append root's data + arr = [...arr, root.value]; + + // Store right subtree + const right = storeInorder(root.rightChild); + arr = [...arr, ...right]; + return arr; +} + +// Helper function to copy elements from sorted array to make BST while keeping same structure +// Runtime complexity iof this function is O(n) where n is number of nodes, as we are each node of tree one time. +function arrayToBST(arr, root) { + const node = root; + // Base case + if (!node) return null; + + const bstNode = new Node(); + // First update the left subtree + const leftChild = arrayToBST(arr, node.leftChild); + if (leftChild) { + bstNode.leftChild = leftChild; + } + + // update the root's data and remove it from sorted array + // eslint-disable-next-line no-param-reassign + bstNode.value = arr.shift(); + + // Finally update the right subtree + const rightChild = arrayToBST(arr, node.rightChild); + if (rightChild) { + bstNode.rightChild = rightChild; + } + + return bstNode; +} + +function binaryTreeToBST(bTree) { + // Tree is empty + if (!bTree.root) return null; + const arr = bTree.preOrder(); + arr.sort((a, b) => a - b); + const bst = arrayToBST(arr, bTree.root); + return bst; +} + +module.exports = { + binaryTreeToBST, + storeInorder, +};