From ce53fee92fd6def93e81150e14a9445a492ec79b Mon Sep 17 00:00:00 2001 From: Madhur Panwar <39766613+mdrpanwar@users.noreply.github.com> Date: Wed, 20 Oct 2021 21:08:21 +0530 Subject: [PATCH] Add Implementation of Tree Sort and Generic Type BST (#2638) --- DataStructures/Trees/BSTRecursive.java | 2 +- DataStructures/Trees/BSTRecursiveGeneric.java | 296 ++++++++++++++++++ Sorts/TreeSort.java | 113 +++++++ 3 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 DataStructures/Trees/BSTRecursiveGeneric.java create mode 100644 Sorts/TreeSort.java diff --git a/DataStructures/Trees/BSTRecursive.java b/DataStructures/Trees/BSTRecursive.java index b6536a7b..3802ceb4 100644 --- a/DataStructures/Trees/BSTRecursive.java +++ b/DataStructures/Trees/BSTRecursive.java @@ -26,7 +26,7 @@ public class BSTRecursive { /** main function for tests */ public static void main(String[] args) { - BSTIterative tree = new BSTIterative(); + BSTRecursive tree = new BSTRecursive(); tree.add(5); tree.add(10); tree.add(9); diff --git a/DataStructures/Trees/BSTRecursiveGeneric.java b/DataStructures/Trees/BSTRecursiveGeneric.java new file mode 100644 index 00000000..a3b117a6 --- /dev/null +++ b/DataStructures/Trees/BSTRecursiveGeneric.java @@ -0,0 +1,296 @@ +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; + } + } +} diff --git a/Sorts/TreeSort.java b/Sorts/TreeSort.java new file mode 100644 index 00000000..126625db --- /dev/null +++ b/Sorts/TreeSort.java @@ -0,0 +1,113 @@ +package Sorts; + +import static Sorts.SortUtils.print; + +import java.util.List; + +/** + *

Implementation of the Tree Sort algorithm

+ * + *

+ * Tree Sort: A sorting algorithm which constructs a Binary Search Tree + * using the unsorted data and then outputs the data by inorder traversal + * of the tree. + * + * Reference: https://en.wikipedia.org/wiki/Tree_sort + *

+ * + * @author Madhur Panwar (https://github.com/mdrpanwar) + */ +public class TreeSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] unsortedArray) { + return doTreeSortArray(unsortedArray); + } + + @Override + public > List sort(List unsortedList) { + return doTreeSortList(unsortedList); + } + + private > T[] doTreeSortArray(T[] unsortedArray) { + // create a generic BST tree + DataStructures.Trees.BSTRecursiveGeneric tree = new DataStructures.Trees.BSTRecursiveGeneric(); + + // add all elements to the tree + for(T element: unsortedArray) { + tree.add(element); + } + + // get the sorted list by inorder traversal of the tree + List sortedList = tree.inorderSort(); + + // add the elements back to the initial array + int i = 0; + for(T element: sortedList) { + unsortedArray[i++] = element; + } + + // return the array + return unsortedArray; + } + + private > List doTreeSortList(List unsortedList) { + // create a generic BST tree + DataStructures.Trees.BSTRecursiveGeneric tree = new DataStructures.Trees.BSTRecursiveGeneric(); + + // add all elements to the tree + for(T element: unsortedList) { + tree.add(element); + } + + // get the sorted list by inorder traversal of the tree and return it + return tree.inorderSort(); + } + + public static void main(String[] args) { + TreeSort treeSort = new TreeSort(); + + // ==== Integer Array ======= + System.out.println("Testing for Integer Array...."); + Integer[] a = { 3, -7, 45, 1, 343, -5, 2, 9 }; + System.out.print(String.format("%-10s", "unsorted: ")); + print(a); + a = treeSort.sort(a); + System.out.print(String.format("%-10s", "sorted: ")); + print(a); + System.out.println(); + + // ==== Integer List ======= + System.out.println("Testing for Integer List...."); + List intList = List.of(3, -7, 45, 1, 343, -5, 2, 9); + System.out.print(String.format("%-10s", "unsorted: ")); + print(intList); + intList = treeSort.sort(intList); + System.out.print(String.format("%-10s", "sorted: ")); + print(intList); + System.out.println(); + + + // ==== String Array ======= + System.out.println("Testing for String Array...."); + String[] b = { "banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple" }; + System.out.print(String.format("%-10s", "unsorted: ")); + print(b); + b = treeSort.sort(b); + System.out.print(String.format("%-10s", "sorted: ")); + print(b); + System.out.println(); + + // ==== String List ======= + System.out.println("Testing for String List...."); + List stringList = List.of("banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"); + System.out.print(String.format("%-10s", "unsorted: ")); + print(stringList); + stringList = treeSort.sort(stringList); + System.out.print(String.format("%-10s", "sorted: ")); + print(stringList); + + } + +} +