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 @@ +/** + * + * + *
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 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;
+ }
+ }
+}
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.
+ *
+ *