Merge pull request #1421 from Lakhan-Nad/master

DS: Binary Search Tree added Closes #1420
This commit is contained in:
Stepfen Shawn 2020-08-19 09:07:40 +08:00 committed by GitHub
commit 35ccbd982d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 531 additions and 0 deletions

View File

@ -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)

View File

@ -0,0 +1,287 @@
/**
*
*
* <h1>Binary Search Tree (Iterative)</h1>
*
* <p>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<Node> st = new Stack<Node>();
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<Node> st = new Stack<Node>();
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<Node> st = new Stack<Node>();
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 static class Node {
int data;
Node left;
Node right;
/** Constructor with data as parameter */
Node(int d) {
data = d;
left = null;
right = null;
}
}
}

View File

@ -0,0 +1,242 @@
/**
*
*
* <h1>Binary Search Tree (Recursive)</h1>
*
* 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.
*
* <p>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;
}
}
}