package DataStructures.Trees; import java.util.ArrayList; import java.util.List; /** *

Binary Search Tree (Recursive) Generic Type Implementation

* *

* A recursive implementation of generic type BST. * * Reference: https://en.wikipedia.org/wiki/Binary_search_tree *

* * @author [Madhur Panwar](https://github.com/mdrpanwar) */ public class BSTRecursiveGeneric> { /** only data member is root of BST */ private Node root; /** Constructor use to initialize node as null */ public BSTRecursiveGeneric() { root = null; } /** main function for testing */ public static void main(String[] args) { System.out.println("Testing for integer data..."); // Integer DataStructures.Trees.BSTRecursiveGeneric integerTree = new DataStructures.Trees.BSTRecursiveGeneric(); integerTree.add(5); integerTree.add(10); integerTree.add(9); assert !integerTree.find(4) : "4 is not yet present in BST"; assert integerTree.find(10) : "10 should be present in BST"; integerTree.remove(9); assert !integerTree.find(9) : "9 was just deleted from BST"; integerTree.remove(1); assert !integerTree.find(1) : "Since 1 was not present so find deleting would do no change"; integerTree.add(20); integerTree.add(70); assert integerTree.find(70) : "70 was inserted but not found"; /* Will print in following order 5 10 20 70 */ integerTree.inorder(); System.out.println(); System.out.println("Testing for string data..."); // String DataStructures.Trees.BSTRecursiveGeneric stringTree = new DataStructures.Trees.BSTRecursiveGeneric(); stringTree.add("banana"); stringTree.add("pineapple"); stringTree.add("date"); assert !stringTree.find("girl") : "girl is not yet present in BST"; assert stringTree.find("pineapple") : "10 should be present in BST"; stringTree.remove("date"); assert !stringTree.find("date") : "date was just deleted from BST"; stringTree.remove("boy"); assert !stringTree.find("boy") : "Since boy was not present so deleting would do no change"; stringTree.add("india"); stringTree.add("hills"); assert stringTree.find("hills") : "hills was inserted but not found"; /* Will print in following order banana hills india pineapple */ stringTree.inorder(); } /** * Recursive method to delete a data if present in BST. * * @param node the node under which to (recursively) 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, T data) { if (node == null) { System.out.println("No such data present in BST."); } else if (node.data.compareTo(data) > 0) { node.left = delete(node.left, data); } else if (node.data.compareTo(data) < 0) { 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, T data) { if (node == null) { node = new Node<>(data); } else if (node.data.compareTo(data) > 0) { node.left = insert(node.left, data); } else if (node.data.compareTo(data) < 0) { 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 traversal 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); } } /** * Recursively traverse the tree using inorder traversal * and keep adding elements to argument list. * * @param node the root node * @param sortedList the list to add the srted elements into */ private void inOrderSort(Node node, List sortedList) { if (node == null) { return; } if (node.left != null) { inOrderSort(node.left, sortedList); } sortedList.add(node.data); if (node.right != null) { inOrderSort(node.right, sortedList); } } /** * Serach recursively if the given value is present in BST or not. * * @param node the node under which to check * @param data the value to be checked * @return boolean if data is present or not */ private boolean search(Node node, T data) { if (node == null) { return false; } else if (node.data.compareTo(data) == 0) { return true; } else if (node.data.compareTo(data) > 0) { 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(T 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(T 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 } /** return a sorted list by traversing the tree elements using inorder traversal */ public List inorderSort() { List sortedList = new ArrayList<>(); inOrderSort(this.root, sortedList); return sortedList; } /** 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 line } /** 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 line } /** * To check if given value is present in tree or not. * * @param data the data to be found for */ public boolean find(T 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 generic Node class used for building binary search tree */ private static class Node { T data; Node left; Node right; /** Constructor with data as parameter */ Node(T d) { data = d; left = null; right = null; } } }