mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-08 18:32:56 +08:00
Add Implementation of Tree Sort and Generic Type BST (#2638)
This commit is contained in:
@ -26,7 +26,7 @@ public class BSTRecursive {
|
|||||||
|
|
||||||
/** main function for tests */
|
/** main function for tests */
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
BSTIterative tree = new BSTIterative();
|
BSTRecursive tree = new BSTRecursive();
|
||||||
tree.add(5);
|
tree.add(5);
|
||||||
tree.add(10);
|
tree.add(10);
|
||||||
tree.add(9);
|
tree.add(9);
|
||||||
|
296
DataStructures/Trees/BSTRecursiveGeneric.java
Normal file
296
DataStructures/Trees/BSTRecursiveGeneric.java
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
package DataStructures.Trees;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>Binary Search Tree (Recursive) Generic Type Implementation</h1>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* A recursive implementation of generic type BST.
|
||||||
|
*
|
||||||
|
* Reference: https://en.wikipedia.org/wiki/Binary_search_tree
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author [Madhur Panwar](https://github.com/mdrpanwar)
|
||||||
|
*/
|
||||||
|
public class BSTRecursiveGeneric<T extends Comparable<T>> {
|
||||||
|
/** only data member is root of BST */
|
||||||
|
private Node<T> 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<Integer> integerTree = new DataStructures.Trees.BSTRecursiveGeneric<Integer>();
|
||||||
|
|
||||||
|
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<String> stringTree = new DataStructures.Trees.BSTRecursiveGeneric<String>();
|
||||||
|
|
||||||
|
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<T> delete(Node<T> 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<T> temp = node.right;
|
||||||
|
node.right = null;
|
||||||
|
node = temp;
|
||||||
|
} else if (node.right == null) { // Only left node is present
|
||||||
|
Node<T> temp = node.left;
|
||||||
|
node.left = null;
|
||||||
|
node = temp;
|
||||||
|
} else { // both child are present
|
||||||
|
Node<T> 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<T> insert(Node<T> 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<T> 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<T> 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<T> 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<T> node, List<T> 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<T> 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<T> inorderSort() {
|
||||||
|
List<T> 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> {
|
||||||
|
T data;
|
||||||
|
Node<T> left;
|
||||||
|
Node<T> right;
|
||||||
|
|
||||||
|
/** Constructor with data as parameter */
|
||||||
|
Node(T d) {
|
||||||
|
data = d;
|
||||||
|
left = null;
|
||||||
|
right = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
113
Sorts/TreeSort.java
Normal file
113
Sorts/TreeSort.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package Sorts;
|
||||||
|
|
||||||
|
import static Sorts.SortUtils.print;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1> Implementation of the Tree Sort algorithm</h1>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Madhur Panwar (https://github.com/mdrpanwar)
|
||||||
|
*/
|
||||||
|
public class TreeSort implements SortAlgorithm {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Comparable<T>> T[] sort(T[] unsortedArray) {
|
||||||
|
return doTreeSortArray(unsortedArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Comparable<T>> List<T> sort(List<T> unsortedList) {
|
||||||
|
return doTreeSortList(unsortedList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Comparable<T>> T[] doTreeSortArray(T[] unsortedArray) {
|
||||||
|
// create a generic BST tree
|
||||||
|
DataStructures.Trees.BSTRecursiveGeneric<T> tree = new DataStructures.Trees.BSTRecursiveGeneric<T>();
|
||||||
|
|
||||||
|
// add all elements to the tree
|
||||||
|
for(T element: unsortedArray) {
|
||||||
|
tree.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the sorted list by inorder traversal of the tree
|
||||||
|
List<T> 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 <T extends Comparable<T>> List<T> doTreeSortList(List<T> unsortedList) {
|
||||||
|
// create a generic BST tree
|
||||||
|
DataStructures.Trees.BSTRecursiveGeneric<T> tree = new DataStructures.Trees.BSTRecursiveGeneric<T>();
|
||||||
|
|
||||||
|
// 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<Integer> 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<String> 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user