diff --git a/DataStructures/Trees/BSTIterative.java b/DataStructures/Trees/BSTIterative.java new file mode 100644 index 000000000..b08b0057a --- /dev/null +++ b/DataStructures/Trees/BSTIterative.java @@ -0,0 +1,265 @@ +/** + * + * + *

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; + } + + /** + * 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 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 000000000..9405e60c7 --- /dev/null +++ b/DataStructures/Trees/BSTRecursive.java @@ -0,0 +1,219 @@ +/** + * + * + *

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; + } + + /** + * Recursive method to delete a data if present in BST. + * + * @param root 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 root, int data) { + if (root == null) { + System.out.println("No such data present in BST."); + } else if (root.data > data) { + root.left = delete(root.left, data); + } else if (root.data < data) { + root.right = delete(root.right, data); + } else { + if (root.right == null && root.left == null) { // If it is leaf node + root = null; + } else if (root.left == null) { // If only right node is present + Node temp = root.right; + root.right = null; + root = temp; + } else if (root.right == null) { // Only left node is present + Node temp = root.left; + root.left = null; + root = temp; + } else { // both child are present + Node temp = root.right; + // Find leftmost child of right subtree + while (temp.left != null) { + temp = temp.left; + } + root.data = temp.data; + root.right = delete(root.right, temp.data); + } + } + return root; + } + + /** + * Recursive insertion of value in BST. + * + * @param root 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 root, int data) { + if (root == null) { + root = new Node(data); + } else if (root.data > data) { + root.left = insert(root.left, data); + } else if (root.data < data) { + root.right = insert(root.right, data); + } + return root; + } + + /** + * Recursively print Preorder traversal of the BST + * + * @param root + */ + private void preOrder(Node root) { + if (root == null) { + return; + } + System.out.print(root.data + " "); + if (root.left != null) { + preOrder(root.left); + } + if (root.right != null) { + preOrder(root.right); + } + } + + /** + * Recursively print Postorder travesal of BST. + * + * @param root + */ + private void postOrder(Node root) { + if (root == null) { + return; + } + if (root.left != null) { + postOrder(root.left); + } + if (root.right != null) { + postOrder(root.right); + } + System.out.print(root.data + " "); + } + + /** + * Recursively print Inorder traversal of BST. + * + * @param root + */ + private void inOrder(Node root) { + if (root == null) { + return; + } + if (root.left != null) { + inOrder(root.left); + } + System.out.print(root.data + " "); + if (root.right != null) { + inOrder(root.right); + } + } + + /** + * Serach recursively if the given value is present in BST or not. + * + * @param root the current node to check + * @param data the value to be checked + * @return boolean if data is present or not + */ + private boolean search(Node root, int data) { + if (root == null) { + return false; + } else if (root.data == data) { + return true; + } else if (root.data > data) { + return search(root.left, data); + } else { + return search(root.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 + */ + public void 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 class Node { + int data; + Node left; + Node right; + + /** Constructor with data as parameter */ + Node(int d) { + data = d; + left = null; + right = null; + } + } +}