mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-09 03:59:38 +08:00
DS: Binary Search Tree added Closes #1420
This commit is contained in:
265
DataStructures/Trees/BSTIterative.java
Normal file
265
DataStructures/Trees/BSTIterative.java
Normal file
@ -0,0 +1,265 @@
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <h1>Binary Search Tree (Iterative)</h1>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 class Node {
|
||||
int data;
|
||||
Node left;
|
||||
Node right;
|
||||
|
||||
/** Constructor with data as parameter */
|
||||
Node(int d) {
|
||||
data = d;
|
||||
left = null;
|
||||
right = null;
|
||||
}
|
||||
}
|
||||
}
|
219
DataStructures/Trees/BSTRecursive.java
Normal file
219
DataStructures/Trees/BSTRecursive.java
Normal file
@ -0,0 +1,219 @@
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method to delete a data if present in BST.
|
||||
*
|
||||
* @param root 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 root, int data) {
|
||||
if (root == null) {
|
||||
System.out.println("No such data present in BST.");
|
||||
} else if (root.data > data) {
|
||||
root.left = delete(root.left, data);
|
||||
} else if (root.data < data) {
|
||||
root.right = delete(root.right, data);
|
||||
} else {
|
||||
if (root.right == null && root.left == null) { // If it is leaf node
|
||||
root = null;
|
||||
} else if (root.left == null) { // If only right node is present
|
||||
Node temp = root.right;
|
||||
root.right = null;
|
||||
root = temp;
|
||||
} else if (root.right == null) { // Only left node is present
|
||||
Node temp = root.left;
|
||||
root.left = null;
|
||||
root = temp;
|
||||
} else { // both child are present
|
||||
Node temp = root.right;
|
||||
// Find leftmost child of right subtree
|
||||
while (temp.left != null) {
|
||||
temp = temp.left;
|
||||
}
|
||||
root.data = temp.data;
|
||||
root.right = delete(root.right, temp.data);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive insertion of value in BST.
|
||||
*
|
||||
* @param root 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 root, int data) {
|
||||
if (root == null) {
|
||||
root = new Node(data);
|
||||
} else if (root.data > data) {
|
||||
root.left = insert(root.left, data);
|
||||
} else if (root.data < data) {
|
||||
root.right = insert(root.right, data);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively print Preorder traversal of the BST
|
||||
*
|
||||
* @param root
|
||||
*/
|
||||
private void preOrder(Node root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
System.out.print(root.data + " ");
|
||||
if (root.left != null) {
|
||||
preOrder(root.left);
|
||||
}
|
||||
if (root.right != null) {
|
||||
preOrder(root.right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively print Postorder travesal of BST.
|
||||
*
|
||||
* @param root
|
||||
*/
|
||||
private void postOrder(Node root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
if (root.left != null) {
|
||||
postOrder(root.left);
|
||||
}
|
||||
if (root.right != null) {
|
||||
postOrder(root.right);
|
||||
}
|
||||
System.out.print(root.data + " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively print Inorder traversal of BST.
|
||||
*
|
||||
* @param root
|
||||
*/
|
||||
private void inOrder(Node root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
if (root.left != null) {
|
||||
inOrder(root.left);
|
||||
}
|
||||
System.out.print(root.data + " ");
|
||||
if (root.right != null) {
|
||||
inOrder(root.right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serach recursively if the given value is present in BST or not.
|
||||
*
|
||||
* @param root the current node to check
|
||||
* @param data the value to be checked
|
||||
* @return boolean if data is present or not
|
||||
*/
|
||||
private boolean search(Node root, int data) {
|
||||
if (root == null) {
|
||||
return false;
|
||||
} else if (root.data == data) {
|
||||
return true;
|
||||
} else if (root.data > data) {
|
||||
return search(root.left, data);
|
||||
} else {
|
||||
return search(root.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
|
||||
*/
|
||||
public void 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 class Node {
|
||||
int data;
|
||||
Node left;
|
||||
Node right;
|
||||
|
||||
/** Constructor with data as parameter */
|
||||
Node(int d) {
|
||||
data = d;
|
||||
left = null;
|
||||
right = null;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user