diff --git a/DIRECTORY.md b/DIRECTORY.md index d70ba9fd..6fda98a6 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -81,6 +81,8 @@ * Trees * [AVLTree](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/AVLTree.java) * [BinaryTree](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/BinaryTree.java) + * [BSTIterative](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/BSTIterative.java) + * [BSTRecursive](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/BSTRecursive.java) * [GenericTree](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/GenericTree.java) * [LevelOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/LevelOrderTraversal.java) * [LevelOrderTraversalQueue](https://github.com/TheAlgorithms/Java/blob/master/DataStructures/Trees/LevelOrderTraversalQueue.java) diff --git a/DataStructures/Trees/BSTIterative.java b/DataStructures/Trees/BSTIterative.java new file mode 100644 index 00000000..8c8e254b --- /dev/null +++ b/DataStructures/Trees/BSTIterative.java @@ -0,0 +1,287 @@ +/** + * + * + *

Binary Search Tree (Iterative)

+ * + *

An implementation of BST iteratively. Binary Search Tree is a binary tree which satisfies + * three properties: left child is less than root node, right child is grater than root node, both + * left and right childs must themselves be a BST. + * + * @author [Lakhan Nad](https://github.com/Lakhan-Nad) + */ +import java.util.Stack; + +public class BSTIterative { + /** Reference for the node of BST. */ + private Node root; + + /** Default Constructor Initializes the root of BST with null. */ + BSTIterative() { + root = null; + } + + /** main function for tests */ + public static void main(String[] args) { + BSTIterative tree = new BSTIterative(); + tree.add(3); + tree.add(2); + tree.add(9); + assert !tree.find(4) : "4 is not yet present in BST"; + assert tree.find(2) : "2 should be present in BST"; + tree.remove(2); + assert !tree.find(2) : "2 was just deleted from BST"; + tree.remove(1); + assert !tree.find(1) : "Since 1 was not present so find deleting would do no change"; + tree.add(30); + tree.add(40); + assert tree.find(40) : "40 was inserted but not found"; + /* + Will print following order + 3 9 30 40 + */ + tree.inorder(); + } + + /** + * A method to insert a new value in BST. If the given value is already present in BST the + * insertion is ignored. + * + * @param data the value to be inserted + */ + public void add(int data) { + Node parent = null; + Node temp = this.root; + int rightOrLeft = -1; + /* Finds the proper place this node can + * be placed in according to rules of BST. + */ + while (temp != null) { + if (temp.data > data) { + parent = temp; + temp = parent.left; + rightOrLeft = 0; + } else if (temp.data < data) { + parent = temp; + temp = parent.right; + rightOrLeft = 1; + } else { + System.out.println(data + " is already present in BST."); + return; // if data already present we ignore insertion + } + } + /* Creates a newNode with the value passed + * Since this data doesn't already exists + */ + Node newNode = new Node(data); + /* If the parent node is null + * then the insertion is to be done in + * root itself. + */ + if (parent == null) { + this.root = newNode; + } else { + /* Check if insertion is to be made in + * left or right subtree. + */ + if (rightOrLeft == 0) { + parent.left = newNode; + } else { + parent.right = newNode; + } + } + } + + /** + * A method to delete the node in BST. If node is present it will be deleted + * + * @param data the value that needs to be deleted + */ + public void remove(int data) { + Node parent = null; + Node temp = this.root; + int rightOrLeft = -1; + /* Find the parent of the node and node itself + * That is to be deleted. + * parent variable store parent + * temp stores node itself. + * rightOrLeft use to keep track weather child + * is left or right subtree + */ + while (temp != null) { + if (temp.data == data) { + break; + } else if (temp.data > data) { + parent = temp; + temp = parent.left; + rightOrLeft = 0; + } else { + parent = temp; + temp = parent.right; + rightOrLeft = 1; + } + } + /* If temp is null than node with given value is not + * present in our tree. + */ + if (temp != null) { + Node replacement; // used to store the new values for replacing nodes + if (temp.right == null && temp.left == null) { // Leaf node Case + replacement = null; + } else if (temp.right == null) { // Node with only right child + replacement = temp.left; + temp.left = null; + } else if (temp.left == null) { // Node with only left child + replacement = temp.right; + temp.right = null; + } else { + /* If both left and right child are present + * we replace this nodes data with + * leftmost node's data in its right subtree + * to maintain the balance of BST. + * And then delete that node + */ + if (temp.right.left == null) { + temp.data = temp.right.data; + replacement = temp; + temp.right = temp.right.right; + } else { + Node parent2 = temp.right; + Node child = temp.right.left; + while (child.left != null) { + parent2 = child; + child = parent2.left; + } + temp.data = child.data; + parent2.left = child.right; + replacement = temp; + } + } + /* Change references of parent after + * deleting the child. + */ + if (parent == null) { + this.root = replacement; + } else { + if (rightOrLeft == 0) { + parent.left = replacement; + } else { + parent.right = replacement; + } + } + } + } + + /** A method for inorder traversal of BST. */ + public void inorder() { + if (this.root == null) { + System.out.println("This BST is empty."); + return; + } + System.out.println("Inorder traversal of this tree is:"); + Stack st = new Stack(); + Node cur = this.root; + while (cur != null || !st.empty()) { + while (cur != null) { + st.push(cur); + cur = cur.left; + } + cur = st.pop(); + System.out.print(cur.data + " "); + cur = cur.right; + } + System.out.println(); // for next line + } + + /** A method used to print postorder traversal of BST. */ + public void postorder() { + if (this.root == null) { + System.out.println("This BST is empty."); + return; + } + System.out.println("Postorder traversal of this tree is:"); + Stack st = new Stack(); + Node cur = this.root, temp2; + while (cur != null || !st.empty()) { + if (cur != null) { + st.push(cur); + cur = cur.left; + } else { + temp2 = st.peek(); + if (temp2.right != null) { + cur = temp2.right; + } else { + st.pop(); + while (!st.empty() && st.peek().right == temp2) { + System.out.print(temp2.data + " "); + temp2 = st.pop(); + } + System.out.print(temp2.data + " "); + } + } + } + System.out.println(); // for next line + } + + /** Method used to display preorder traversal of BST. */ + public void preorder() { + if (this.root == null) { + System.out.println("This BST is empty."); + return; + } + System.out.println("Preorder traversal of this tree is:"); + Stack st = new Stack(); + st.push(this.root); + Node temp; + while (!st.empty()) { + temp = st.pop(); + System.out.print(temp.data + " "); + if (temp.right != null) { + st.push(temp.right); + } + if (temp.left != null) { + st.push(temp.left); + } + } + System.out.println(); // for next line + } + + /** + * A method to check if given data exists in out Binary Search Tree. + * + * @param data the value that needs to be searched for + * @return boolean representing if the value was find + */ + public boolean find(int data) { + Node temp = this.root; + /* Check if node exists + */ + while (temp != null) { + if (temp.data > data) { + temp = temp.left; + } else if (temp.data < data) { + temp = temp.right; + } else { + /* If found return true + */ + System.out.println(data + " is present in the BST."); + return true; + } + } + System.out.println(data + " not found."); + return false; + } + + /** The Node class used for building binary search tree */ + private static class Node { + int data; + Node left; + Node right; + + /** Constructor with data as parameter */ + Node(int d) { + data = d; + left = null; + right = null; + } + } +} diff --git a/DataStructures/Trees/BSTRecursive.java b/DataStructures/Trees/BSTRecursive.java new file mode 100644 index 00000000..a228326b --- /dev/null +++ b/DataStructures/Trees/BSTRecursive.java @@ -0,0 +1,242 @@ +/** + * + * + *

Binary Search Tree (Recursive)

+ * + * An implementation of BST recursively. In recursive implementation the checks are down the tree + * First root is checked if not found then its childs are checked Binary Search Tree is a binary + * tree which satisfies three properties: left child is less than root node, right child is grater + * than root node, both left and right childs must themselves be a BST. + * + *

I have made public functions as methods and to actually implement recursive approach I have + * used private methods + * + * @author [Lakhan Nad](https://github.com/Lakhan-Nad) + */ +public class BSTRecursive { + /** only data member is root of BST */ + private Node root; + + /** Constructor use to initialize node as null */ + BSTRecursive() { + root = null; + } + + /** main function for tests */ + public static void main(String[] args) { + BSTIterative tree = new BSTIterative(); + tree.add(5); + tree.add(10); + tree.add(9); + assert !tree.find(4) : "4 is not yet present in BST"; + assert tree.find(10) : "10 should be present in BST"; + tree.remove(9); + assert !tree.find(9) : "9 was just deleted from BST"; + tree.remove(1); + assert !tree.find(1) : "Since 1 was not present so find deleting would do no change"; + tree.add(20); + tree.add(70); + assert tree.find(70) : "70 was inserted but not found"; + /* + Will print in following order + 5 10 20 70 + */ + tree.inorder(); + } + + /** + * Recursive method to delete a data if present in BST. + * + * @param node the current node to search for data + * @param data the value to be deleted + * @return Node the updated value of root parameter after delete operation + */ + private Node delete(Node node, int data) { + if (node == null) { + System.out.println("No such data present in BST."); + } else if (node.data > data) { + node.left = delete(node.left, data); + } else if (node.data < data) { + node.right = delete(node.right, data); + } else { + if (node.right == null && node.left == null) { // If it is leaf node + node = null; + } else if (node.left == null) { // If only right node is present + Node temp = node.right; + node.right = null; + node = temp; + } else if (node.right == null) { // Only left node is present + Node temp = node.left; + node.left = null; + node = temp; + } else { // both child are present + Node temp = node.right; + // Find leftmost child of right subtree + while (temp.left != null) { + temp = temp.left; + } + node.data = temp.data; + node.right = delete(node.right, temp.data); + } + } + return node; + } + + /** + * Recursive insertion of value in BST. + * + * @param node to check if the data can be inserted in current node or its subtree + * @param data the value to be inserted + * @return the modified value of the root parameter after insertion + */ + private Node insert(Node node, int data) { + if (node == null) { + node = new Node(data); + } else if (node.data > data) { + node.left = insert(node.left, data); + } else if (node.data < data) { + node.right = insert(node.right, data); + } + return node; + } + + /** + * Recursively print Preorder traversal of the BST + * + * @param node the root node + */ + private void preOrder(Node node) { + if (node == null) { + return; + } + System.out.print(node.data + " "); + if (node.left != null) { + preOrder(node.left); + } + if (node.right != null) { + preOrder(node.right); + } + } + + /** + * Recursively print Postorder travesal of BST. + * + * @param node the root node + */ + private void postOrder(Node node) { + if (node == null) { + return; + } + if (node.left != null) { + postOrder(node.left); + } + if (node.right != null) { + postOrder(node.right); + } + System.out.print(node.data + " "); + } + + /** + * Recursively print Inorder traversal of BST. + * + * @param node the root node + */ + private void inOrder(Node node) { + if (node == null) { + return; + } + if (node.left != null) { + inOrder(node.left); + } + System.out.print(node.data + " "); + if (node.right != null) { + inOrder(node.right); + } + } + + /** + * Serach recursively if the given value is present in BST or not. + * + * @param node the current node to check + * @param data the value to be checked + * @return boolean if data is present or not + */ + private boolean search(Node node, int data) { + if (node == null) { + return false; + } else if (node.data == data) { + return true; + } else if (node.data > data) { + return search(node.left, data); + } else { + return search(node.right, data); + } + } + + /** + * add in BST. if the value is not already present it is inserted or else no change takes place. + * + * @param data the value to be inserted + */ + public void add(int data) { + this.root = insert(this.root, data); + } + + /** + * If data is present in BST delete it else do nothing. + * + * @param data the value to be removed + */ + public void remove(int data) { + this.root = delete(this.root, data); + } + + /** To call inorder traversal on tree */ + public void inorder() { + System.out.println("Inorder traversal of this tree is:"); + inOrder(this.root); + System.out.println(); // for next line + } + + /** To call postorder traversal on tree */ + public void postorder() { + System.out.println("Postorder traversal of this tree is:"); + postOrder(this.root); + System.out.println(); // for next li + } + + /** To call preorder traversal on tree. */ + public void preorder() { + System.out.println("Preorder traversal of this tree is:"); + preOrder(this.root); + System.out.println(); // for next li + } + + /** + * To check if given value is present in tree or not. + * + * @param data the data to be found for + */ + public boolean find(int data) { + if (search(this.root, data)) { + System.out.println(data + " is present in given BST."); + return true; + } + System.out.println(data + " not found."); + return false; + } + + /** The Node class used for building binary search tree */ + private static class Node { + int data; + Node left; + Node right; + + /** Constructor with data as parameter */ + Node(int d) { + data = d; + left = null; + right = null; + } + } +}