mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-27 14:34:05 +08:00
Change project structure to a Maven Java project + Refactor (#2816)
This commit is contained in:

committed by
GitHub

parent
8e533d2617
commit
9fb3364ccc
137
src/main/java/com/thealgorithms/datastructures/trees/AVLSimple
Normal file
137
src/main/java/com/thealgorithms/datastructures/trees/AVLSimple
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
/*
|
||||
* Avl is algo that balance itself while adding new alues to tree
|
||||
* by rotating branches of binary tree and make itself Binary seaarch tree
|
||||
* there are four cases which has to tackle
|
||||
* rotating - left right ,left left,right right,right left
|
||||
|
||||
Test Case:
|
||||
|
||||
AVLTree tree=new AVLTree();
|
||||
tree.insert(20);
|
||||
tree.insert(25);
|
||||
tree.insert(30);
|
||||
tree.insert(10);
|
||||
tree.insert(5);
|
||||
tree.insert(15);
|
||||
tree.insert(27);
|
||||
tree.insert(19);
|
||||
tree.insert(16);
|
||||
|
||||
tree.display();
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class AVLTree {
|
||||
private class Node{
|
||||
int data;
|
||||
int height;
|
||||
Node left;
|
||||
Node right;
|
||||
Node(int data){
|
||||
this.data=data;
|
||||
this.height=1;
|
||||
}
|
||||
|
||||
}
|
||||
private Node root;
|
||||
public void insert(int data) {
|
||||
this.root=insert(this.root,data);
|
||||
}
|
||||
private Node insert(Node node,int item) {
|
||||
if(node==null) {
|
||||
Node add=new Node(item);
|
||||
return add;
|
||||
}
|
||||
if(node.data>item) {
|
||||
node.left=insert(node.left,item);
|
||||
}
|
||||
if(node.data<item) {
|
||||
node.right=insert(node.right,item);
|
||||
}
|
||||
node.height=Math.max(height(node.left),height(node.right))+1;
|
||||
int bf=bf(node);
|
||||
//LL case
|
||||
if(bf>1&&item<node.left.data)
|
||||
return rightRotate(node);
|
||||
//RR case
|
||||
if(bf<-1&&item>node.right.data)
|
||||
return leftRotate(node);
|
||||
//RL case
|
||||
if(bf<-1&&item<node.right.data) {
|
||||
node.right=rightRotate(node.right);
|
||||
return leftRotate(node);
|
||||
}
|
||||
//LR case
|
||||
if(bf>1&&item>node.left.data) {
|
||||
node.left=leftRotate(node.left);
|
||||
return rightRotate(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
public void display() {
|
||||
this.display(this.root);
|
||||
System.out.println(this.root.height);
|
||||
}
|
||||
private void display (Node node) {
|
||||
Strings str="";
|
||||
if(node.left!=null)
|
||||
str+=node.left.data+"=>";
|
||||
else
|
||||
str+="END=>";
|
||||
str+=node.data+"";
|
||||
if(node.right!=null)
|
||||
str+="<="+node.right.data;
|
||||
else
|
||||
str+="<=END";
|
||||
System.out.println(str);
|
||||
if(node.left!=null)
|
||||
display(node.left);
|
||||
if(node.right!=null)
|
||||
display(node.right);
|
||||
}
|
||||
private int height(Node node) {
|
||||
if(node==null) {
|
||||
return 0;
|
||||
}
|
||||
return node.height;
|
||||
|
||||
}
|
||||
private int bf(Node node) {
|
||||
if(node==null)
|
||||
return 0;
|
||||
return height(node.left)-height(node.right);
|
||||
}
|
||||
|
||||
private Node rightRotate(Node c) {
|
||||
Node b=c.left;
|
||||
Node T3=b.right;
|
||||
|
||||
b.right=c;
|
||||
c.left=T3;
|
||||
c.height=Math.max(height(c.left),height(c.right))+1;
|
||||
b.height=Math.max(height(b.left),height(b.right))+1;
|
||||
return b;
|
||||
|
||||
}
|
||||
private Node leftRotate(Node c) {
|
||||
Node b=c.right;
|
||||
Node T3=b.left;
|
||||
|
||||
b.left=c;
|
||||
c.right=T3;
|
||||
c.height=Math.max(height(c.left),height(c.right))+1;
|
||||
b.height=Math.max(height(b.left),height(b.right))+1;
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,255 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
public class AVLTree {
|
||||
|
||||
private Node root;
|
||||
|
||||
private class Node {
|
||||
|
||||
private int key;
|
||||
private int balance;
|
||||
private int height;
|
||||
private Node left, right, parent;
|
||||
|
||||
Node(int k, Node p) {
|
||||
key = k;
|
||||
parent = p;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean insert(int key) {
|
||||
if (root == null) {
|
||||
root = new Node(key, null);
|
||||
} else {
|
||||
Node n = root;
|
||||
Node parent;
|
||||
while (true) {
|
||||
if (n.key == key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent = n;
|
||||
|
||||
boolean goLeft = n.key > key;
|
||||
n = goLeft ? n.left : n.right;
|
||||
|
||||
if (n == null) {
|
||||
if (goLeft) {
|
||||
parent.left = new Node(key, parent);
|
||||
} else {
|
||||
parent.right = new Node(key, parent);
|
||||
}
|
||||
rebalance(parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void delete(Node node) {
|
||||
if (node.left == null && node.right == null) {
|
||||
if (node.parent == null) {
|
||||
root = null;
|
||||
} else {
|
||||
Node parent = node.parent;
|
||||
if (parent.left == node) {
|
||||
parent.left = null;
|
||||
} else {
|
||||
parent.right = null;
|
||||
}
|
||||
rebalance(parent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (node.left != null) {
|
||||
Node child = node.left;
|
||||
while (child.right != null) {
|
||||
child = child.right;
|
||||
}
|
||||
node.key = child.key;
|
||||
delete(child);
|
||||
} else {
|
||||
Node child = node.right;
|
||||
while (child.left != null) {
|
||||
child = child.left;
|
||||
}
|
||||
node.key = child.key;
|
||||
delete(child);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(int delKey) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
Node node = root;
|
||||
Node child = root;
|
||||
|
||||
while (child != null) {
|
||||
node = child;
|
||||
child = delKey >= node.key ? node.right : node.left;
|
||||
if (delKey == node.key) {
|
||||
delete(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rebalance(Node n) {
|
||||
setBalance(n);
|
||||
|
||||
if (n.balance == -2) {
|
||||
if (height(n.left.left) >= height(n.left.right)) {
|
||||
n = rotateRight(n);
|
||||
} else {
|
||||
n = rotateLeftThenRight(n);
|
||||
}
|
||||
|
||||
} else if (n.balance == 2) {
|
||||
if (height(n.right.right) >= height(n.right.left)) {
|
||||
n = rotateLeft(n);
|
||||
} else {
|
||||
n = rotateRightThenLeft(n);
|
||||
}
|
||||
}
|
||||
|
||||
if (n.parent != null) {
|
||||
rebalance(n.parent);
|
||||
} else {
|
||||
root = n;
|
||||
}
|
||||
}
|
||||
|
||||
private Node rotateLeft(Node a) {
|
||||
|
||||
Node b = a.right;
|
||||
b.parent = a.parent;
|
||||
|
||||
a.right = b.left;
|
||||
|
||||
if (a.right != null) {
|
||||
a.right.parent = a;
|
||||
}
|
||||
|
||||
b.left = a;
|
||||
a.parent = b;
|
||||
|
||||
if (b.parent != null) {
|
||||
if (b.parent.right == a) {
|
||||
b.parent.right = b;
|
||||
} else {
|
||||
b.parent.left = b;
|
||||
}
|
||||
}
|
||||
|
||||
setBalance(a, b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
private Node rotateRight(Node a) {
|
||||
|
||||
Node b = a.left;
|
||||
b.parent = a.parent;
|
||||
|
||||
a.left = b.right;
|
||||
|
||||
if (a.left != null) {
|
||||
a.left.parent = a;
|
||||
}
|
||||
|
||||
b.right = a;
|
||||
a.parent = b;
|
||||
|
||||
if (b.parent != null) {
|
||||
if (b.parent.right == a) {
|
||||
b.parent.right = b;
|
||||
} else {
|
||||
b.parent.left = b;
|
||||
}
|
||||
}
|
||||
|
||||
setBalance(a, b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
private Node rotateLeftThenRight(Node n) {
|
||||
n.left = rotateLeft(n.left);
|
||||
return rotateRight(n);
|
||||
}
|
||||
|
||||
private Node rotateRightThenLeft(Node n) {
|
||||
n.right = rotateRight(n.right);
|
||||
return rotateLeft(n);
|
||||
}
|
||||
|
||||
private int height(Node n) {
|
||||
if (n == null) {
|
||||
return -1;
|
||||
}
|
||||
return n.height;
|
||||
}
|
||||
|
||||
private void setBalance(Node... nodes) {
|
||||
for (Node n : nodes) {
|
||||
reheight(n);
|
||||
n.balance = height(n.right) - height(n.left);
|
||||
}
|
||||
}
|
||||
|
||||
public void printBalance() {
|
||||
printBalance(root);
|
||||
}
|
||||
|
||||
private void printBalance(Node n) {
|
||||
if (n != null) {
|
||||
printBalance(n.left);
|
||||
System.out.printf("%s ", n.balance);
|
||||
printBalance(n.right);
|
||||
}
|
||||
}
|
||||
|
||||
private void reheight(Node node) {
|
||||
if (node != null) {
|
||||
node.height = 1 + Math.max(height(node.left), height(node.right));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean search(int key) {
|
||||
Node result = searchHelper(this.root, key);
|
||||
if (result != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Node searchHelper(Node root, int key) {
|
||||
// root is null or key is present at root
|
||||
if (root == null || root.key == key) {
|
||||
return root;
|
||||
}
|
||||
|
||||
// key is greater than root's key
|
||||
if (root.key > key) {
|
||||
return searchHelper(root.left, key); // call the function on the node's left child
|
||||
}
|
||||
// key is less than root's key then
|
||||
// call the function on the node's right child as it is greater
|
||||
return searchHelper(root.right, key);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
AVLTree tree = new AVLTree();
|
||||
|
||||
System.out.println("Inserting values 1 to 10");
|
||||
for (int i = 1; i < 10; i++) {
|
||||
tree.insert(i);
|
||||
}
|
||||
|
||||
System.out.print("Printing balance: ");
|
||||
tree.printBalance();
|
||||
}
|
||||
}
|
@ -0,0 +1,309 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <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) {
|
||||
BSTRecursive tree = new BSTRecursive();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,319 @@
|
||||
package com.thealgorithms.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
|
||||
BSTRecursiveGeneric<Integer> integerTree = new 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
|
||||
BSTRecursiveGeneric<String> stringTree = new 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,334 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* This entire class is used to build a Binary Tree data structure. There is the
|
||||
* Node Class and the Tree Class, both explained below.
|
||||
*/
|
||||
/**
|
||||
* A binary tree is a data structure in which an element has two
|
||||
* successors(children). The left child is usually smaller than the parent, and
|
||||
* the right child is usually bigger.
|
||||
*
|
||||
* @author Unknown
|
||||
*/
|
||||
public class BinaryTree {
|
||||
|
||||
/**
|
||||
* This class implements the nodes that will go on the Binary Tree. They
|
||||
* consist of the data in them, the node to the left, the node to the right,
|
||||
* and the parent from which they came from.
|
||||
*
|
||||
* @author Unknown
|
||||
*/
|
||||
static class Node {
|
||||
|
||||
/**
|
||||
* Data for the node
|
||||
*/
|
||||
public int data;
|
||||
/**
|
||||
* The Node to the left of this one
|
||||
*/
|
||||
public Node left;
|
||||
/**
|
||||
* The Node to the right of this one
|
||||
*/
|
||||
public Node right;
|
||||
/**
|
||||
* The parent of this node
|
||||
*/
|
||||
public Node parent;
|
||||
|
||||
/**
|
||||
* Constructor of Node
|
||||
*
|
||||
* @param value Value to put in the node
|
||||
*/
|
||||
public Node(int value) {
|
||||
data = value;
|
||||
left = null;
|
||||
right = null;
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The root of the Binary Tree
|
||||
*/
|
||||
private Node root;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public BinaryTree() {
|
||||
root = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameterized Constructor
|
||||
*/
|
||||
public BinaryTree(Node root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to find a Node with a certain value
|
||||
*
|
||||
* @param key Value being looked for
|
||||
* @return The node if it finds it, otherwise returns the parent
|
||||
*/
|
||||
public Node find(int key) {
|
||||
Node current = root;
|
||||
while (current != null) {
|
||||
if (key < current.data) {
|
||||
if (current.left == null) {
|
||||
return current; // The key isn't exist, returns the parent
|
||||
}
|
||||
current = current.left;
|
||||
} else if (key > current.data) {
|
||||
if (current.right == null) {
|
||||
return current;
|
||||
}
|
||||
current = current.right;
|
||||
} else { // If you find the value return it
|
||||
return current;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts certain value into the Binary Tree
|
||||
*
|
||||
* @param value Value to be inserted
|
||||
*/
|
||||
public void put(int value) {
|
||||
Node newNode = new Node(value);
|
||||
if (root == null) {
|
||||
root = newNode;
|
||||
} else {
|
||||
// This will return the soon to be parent of the value you're inserting
|
||||
Node parent = find(value);
|
||||
|
||||
// This if/else assigns the new node to be either the left or right child of the parent
|
||||
if (value < parent.data) {
|
||||
parent.left = newNode;
|
||||
parent.left.parent = parent;
|
||||
return;
|
||||
} else {
|
||||
parent.right = newNode;
|
||||
parent.right.parent = parent;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a given value from the Binary Tree
|
||||
*
|
||||
* @param value Value to be deleted
|
||||
* @return If the value was deleted
|
||||
*/
|
||||
public boolean remove(int value) {
|
||||
// temp is the node to be deleted
|
||||
Node temp = find(value);
|
||||
|
||||
// If the value doesn't exist
|
||||
if (temp.data != value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No children
|
||||
if (temp.right == null && temp.left == null) {
|
||||
if (temp == root) {
|
||||
root = null;
|
||||
} // This if/else assigns the new node to be either the left or right child of the parent
|
||||
else if (temp.parent.data < temp.data) {
|
||||
temp.parent.right = null;
|
||||
} else {
|
||||
temp.parent.left = null;
|
||||
}
|
||||
return true;
|
||||
} // Two children
|
||||
else if (temp.left != null && temp.right != null) {
|
||||
Node successor = findSuccessor(temp);
|
||||
|
||||
// The left tree of temp is made the left tree of the successor
|
||||
successor.left = temp.left;
|
||||
successor.left.parent = successor;
|
||||
|
||||
// If the successor has a right child, the child's grandparent is it's new parent
|
||||
if (successor.parent != temp) {
|
||||
if (successor.right != null) {
|
||||
successor.right.parent = successor.parent;
|
||||
successor.parent.left = successor.right;
|
||||
successor.right = temp.right;
|
||||
successor.right.parent = successor;
|
||||
} else {
|
||||
successor.parent.left = null;
|
||||
successor.right = temp.right;
|
||||
successor.right.parent = successor;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp == root) {
|
||||
successor.parent = null;
|
||||
root = successor;
|
||||
return true;
|
||||
} // If you're not deleting the root
|
||||
else {
|
||||
successor.parent = temp.parent;
|
||||
|
||||
// This if/else assigns the new node to be either the left or right child of the parent
|
||||
if (temp.parent.data < temp.data) {
|
||||
temp.parent.right = successor;
|
||||
} else {
|
||||
temp.parent.left = successor;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // One child
|
||||
else {
|
||||
// If it has a right child
|
||||
if (temp.right != null) {
|
||||
if (temp == root) {
|
||||
root = temp.right;
|
||||
return true;
|
||||
}
|
||||
|
||||
temp.right.parent = temp.parent;
|
||||
|
||||
// Assigns temp to left or right child
|
||||
if (temp.data < temp.parent.data) {
|
||||
temp.parent.left = temp.right;
|
||||
} else {
|
||||
temp.parent.right = temp.right;
|
||||
}
|
||||
return true;
|
||||
} // If it has a left child
|
||||
else {
|
||||
if (temp == root) {
|
||||
root = temp.left;
|
||||
return true;
|
||||
}
|
||||
|
||||
temp.left.parent = temp.parent;
|
||||
|
||||
// Assigns temp to left or right side
|
||||
if (temp.data < temp.parent.data) {
|
||||
temp.parent.left = temp.left;
|
||||
} else {
|
||||
temp.parent.right = temp.left;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the Successor to the Node given. Move right once and go
|
||||
* left down the tree as far as you can
|
||||
*
|
||||
* @param n Node that you want to find the Successor of
|
||||
* @return The Successor of the node
|
||||
*/
|
||||
public Node findSuccessor(Node n) {
|
||||
if (n.right == null) {
|
||||
return n;
|
||||
}
|
||||
Node current = n.right;
|
||||
Node parent = n.right;
|
||||
while (current != null) {
|
||||
parent = current;
|
||||
current = current.left;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root of the Binary Tree
|
||||
*
|
||||
* @return the root of the Binary Tree
|
||||
*/
|
||||
public Node getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints leftChild - root - rightChild This is the equivalent of a depth
|
||||
* first search
|
||||
*
|
||||
* @param localRoot The local root of the binary tree
|
||||
*/
|
||||
public void inOrder(Node localRoot) {
|
||||
if (localRoot != null) {
|
||||
inOrder(localRoot.left);
|
||||
System.out.print(localRoot.data + " ");
|
||||
inOrder(localRoot.right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints root - leftChild - rightChild
|
||||
*
|
||||
* @param localRoot The local root of the binary tree
|
||||
*/
|
||||
public void preOrder(Node localRoot) {
|
||||
if (localRoot != null) {
|
||||
System.out.print(localRoot.data + " ");
|
||||
preOrder(localRoot.left);
|
||||
preOrder(localRoot.right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints rightChild - leftChild - root
|
||||
*
|
||||
* @param localRoot The local root of the binary tree
|
||||
*/
|
||||
public void postOrder(Node localRoot) {
|
||||
if (localRoot != null) {
|
||||
postOrder(localRoot.left);
|
||||
postOrder(localRoot.right);
|
||||
System.out.print(localRoot.data + " ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the tree in a breadth first search order This is similar to
|
||||
* pre-order traversal, but instead of being implemented with a stack (or
|
||||
* recursion), it is implemented with a queue
|
||||
*
|
||||
* @param localRoot The local root of the binary tree
|
||||
*/
|
||||
public void bfs(Node localRoot) {
|
||||
// Create a queue for the order of the nodes
|
||||
Queue<Node> queue = new LinkedList<Node>();
|
||||
|
||||
// If the give root is null, then we don't add to the queue
|
||||
// and won't do anything
|
||||
if (localRoot != null) {
|
||||
queue.add(localRoot);
|
||||
}
|
||||
|
||||
// Continue until the queue is empty
|
||||
while (!queue.isEmpty()) {
|
||||
// Get the next node on the queue to visit
|
||||
localRoot = queue.remove();
|
||||
|
||||
// Print the data from the node we are visiting
|
||||
System.out.print(localRoot.data + " ");
|
||||
|
||||
// Add the children to the queue if not null
|
||||
if (localRoot.right != null) {
|
||||
queue.add(localRoot.right);
|
||||
}
|
||||
if (localRoot.left != null) {
|
||||
queue.add(localRoot.left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import com.thealgorithms.datastructures.trees.BinaryTree.Node;
|
||||
|
||||
/**
|
||||
* Problem Statement Ceil value for any number x in a collection is a number y
|
||||
* which is either equal to x or the least greater number than x.
|
||||
*
|
||||
* Problem: Given a binary search tree containing positive integer values. Find
|
||||
* ceil value for a given key in O(lg(n)) time. In case if it is not present
|
||||
* return -1.
|
||||
*
|
||||
* Ex.1. [30,20,40,10,25,35,50] represents level order traversal of a binary
|
||||
* search tree. Find ceil for 10. Answer: 20
|
||||
*
|
||||
* Ex.2. [30,20,40,10,25,35,50] represents level order traversal of a binary
|
||||
* search tree. Find ceil for 22 Answer: 25
|
||||
*
|
||||
* Ex.2. [30,20,40,10,25,35,50] represents level order traversal of a binary
|
||||
* search tree. Find ceil for 52 Answer: -1
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* Solution 1: Brute Force Solution: Do an inorder traversal and save result
|
||||
* into an array. Iterate over the array to get an element equal to or greater
|
||||
* than current key. Time Complexity: O(n) Space Complexity: O(n) for auxillary
|
||||
* array to save inorder representation of tree.
|
||||
* <p>
|
||||
* <p>
|
||||
* Solution 2: Brute Force Solution: Do an inorder traversal and save result
|
||||
* into an array.Since array is sorted do a binary search over the array to get
|
||||
* an element equal to or greater than current key. Time Complexity: O(n) for
|
||||
* traversal of tree and O(lg(n)) for binary search in array. Total = O(n) Space
|
||||
* Complexity: O(n) for auxillary array to save inorder representation of tree.
|
||||
* <p>
|
||||
* <p>
|
||||
* Solution 3: Optimal We can do a DFS search on given tree in following
|
||||
* fashion. i) if root is null then return null because then ceil doesn't exist
|
||||
* ii) If key is lesser than root value than ceil will be in right subtree so
|
||||
* call recursively on right subtree iii) if key is greater than current root,
|
||||
* then either a) the root is ceil b) ceil is in left subtree: call for left
|
||||
* subtree. If left subtree returns a non null value then that will be ceil
|
||||
* otherwise the root is ceil
|
||||
*/
|
||||
public class CeilInBinarySearchTree {
|
||||
|
||||
public static Node getCeil(Node root, int key) {
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// if root value is same as key than root is the ceiling
|
||||
if (root.data == key) {
|
||||
return root;
|
||||
}
|
||||
|
||||
// if root value is lesser than key then ceil must be in right subtree
|
||||
if (root.data < key) {
|
||||
return getCeil(root.right, key);
|
||||
}
|
||||
|
||||
// if root value is greater than key then ceil can be in left subtree or if
|
||||
// it is not in left subtree then current node will be ceil
|
||||
Node result = getCeil(root.left, key);
|
||||
|
||||
// if result is null it means that there is no ceil in children subtrees
|
||||
// and the root is the ceil otherwise the returned node is the ceil.
|
||||
return result == null ? root : result;
|
||||
}
|
||||
}
|
@ -0,0 +1,267 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.Stack;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class will check if a BinaryTree is balanced. A balanced binary tree is
|
||||
* defined as a binary tree where the differenced in height between the left and
|
||||
* right subtree of each node differs by at most one.
|
||||
*
|
||||
* This can be done in both an iterative and recursive fashion. Below,
|
||||
* `isBalancedRecursive()` is implemented in a recursive fashion, and
|
||||
* `isBalancedIterative()` is implemented in an iterative fashion.
|
||||
*
|
||||
* @author [Ian Cowan](https://github.com/iccowan)
|
||||
*/
|
||||
public class CheckIfBinaryTreeBalanced {
|
||||
|
||||
/**
|
||||
* This class implements the BinaryTree for these algorithms
|
||||
*/
|
||||
class BinaryTree {
|
||||
|
||||
/**
|
||||
* The root node of the binary tree
|
||||
*/
|
||||
BTNode root = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements the nodes for the binary tree
|
||||
*/
|
||||
class BTNode {
|
||||
|
||||
/**
|
||||
* The value of the node
|
||||
*/
|
||||
int value;
|
||||
|
||||
/**
|
||||
* The left child of the node
|
||||
*/
|
||||
BTNode left = null;
|
||||
|
||||
/**
|
||||
* The right child of the node
|
||||
*/
|
||||
BTNode right = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
BTNode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive is BT balanced implementation
|
||||
*
|
||||
* @param binaryTree The binary tree to check if balanced
|
||||
*/
|
||||
public boolean isBalancedRecursive(BinaryTree binaryTree) {
|
||||
// Create an array of length 1 to keep track of our balance
|
||||
// Default to true. We use an array so we have an efficient mutable object
|
||||
boolean[] isBalanced = new boolean[1];
|
||||
isBalanced[0] = true;
|
||||
|
||||
// Check for balance and return whether or not we are balanced
|
||||
isBalancedRecursive(binaryTree.root, 0, isBalanced);
|
||||
return isBalanced[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper method to keep track of the depth and balance during
|
||||
* recursion. We effectively perform a modified post-order traversal where
|
||||
* we are looking at the heights of both children of each node in the tree
|
||||
*
|
||||
* @param node The current node to explore
|
||||
* @param depth The current depth of the node
|
||||
* @param isBalanced The array of length 1 keeping track of our balance
|
||||
*/
|
||||
private int isBalancedRecursive(BTNode node, int depth, boolean[] isBalanced) {
|
||||
// If the node is null, we should not explore it and the height is 0
|
||||
// If the tree is already not balanced, might as well stop because we
|
||||
// can't make it balanced now!
|
||||
if (node == null || !isBalanced[0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Visit the left and right children, incrementing their depths by 1
|
||||
int leftHeight = isBalancedRecursive(node.left, depth + 1, isBalanced);
|
||||
int rightHeight = isBalancedRecursive(node.right, depth + 1, isBalanced);
|
||||
|
||||
// If the height of either of the left or right subtrees differ by more
|
||||
// than 1, we cannot be balanced
|
||||
if (Math.abs(leftHeight - rightHeight) > 1) {
|
||||
isBalanced[0] = false;
|
||||
}
|
||||
|
||||
// The height of our tree is the maximum of the heights of the left
|
||||
// and right subtrees plus one
|
||||
return Math.max(leftHeight, rightHeight) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterative is BT balanced implementation
|
||||
*/
|
||||
public boolean isBalancedIterative(BinaryTree binaryTree) {
|
||||
// Default that we are balanced and our algo will prove it wrong
|
||||
boolean isBalanced = true;
|
||||
|
||||
// Create a stack for our post order traversal
|
||||
Stack<BTNode> nodeStack = new Stack<BTNode>();
|
||||
|
||||
// For post order traversal, we'll have to keep track of where we
|
||||
// visited last
|
||||
BTNode lastVisited = null;
|
||||
|
||||
// Create a HashMap to keep track of the subtree heights for each node
|
||||
HashMap<BTNode, Integer> subtreeHeights = new HashMap<BTNode, Integer>();
|
||||
|
||||
// We begin at the root of the tree
|
||||
BTNode node = binaryTree.root;
|
||||
|
||||
// We loop while:
|
||||
// - the node stack is empty and the node we explore is null
|
||||
// AND
|
||||
// - the tree is still balanced
|
||||
while (!(nodeStack.isEmpty() && node == null) && isBalanced) {
|
||||
// If the node is not null, we push it to the stack and continue
|
||||
// to the left
|
||||
if (node != null) {
|
||||
nodeStack.push(node);
|
||||
node = node.left;
|
||||
// Once we hit a node that is null, we are as deep as we can go
|
||||
// to the left
|
||||
} else {
|
||||
// Find the last node we put on the stack
|
||||
node = nodeStack.peek();
|
||||
|
||||
// If the right child of the node has either been visited or
|
||||
// is null, we visit this node
|
||||
if (node.right == null || node.right == lastVisited) {
|
||||
// We assume the left and right heights are 0
|
||||
int leftHeight = 0;
|
||||
int rightHeight = 0;
|
||||
|
||||
// If the right and left children are not null, we must
|
||||
// have already explored them and have a height
|
||||
// for them so let's get that
|
||||
if (node.left != null) {
|
||||
leftHeight = subtreeHeights.get(node.left);
|
||||
}
|
||||
|
||||
if (node.right != null) {
|
||||
rightHeight = subtreeHeights.get(node.right);
|
||||
}
|
||||
|
||||
// If the difference in the height of the right subtree
|
||||
// and left subtree differs by more than 1, we cannot be
|
||||
// balanced
|
||||
if (Math.abs(rightHeight - leftHeight) > 1) {
|
||||
isBalanced = false;
|
||||
}
|
||||
|
||||
// The height of the subtree containing this node is the
|
||||
// max of the left and right subtree heighs plus 1
|
||||
subtreeHeights.put(node, Math.max(rightHeight, leftHeight) + 1);
|
||||
|
||||
// We've now visited this node, so we pop it from the stack
|
||||
nodeStack.pop();
|
||||
lastVisited = node;
|
||||
|
||||
// Current visiting node is now null
|
||||
node = null;
|
||||
// If the right child node of this node has not been visited
|
||||
// and is not null, we need to get that child node on the stack
|
||||
} else {
|
||||
node = node.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return whether or not the tree is balanced
|
||||
return isBalanced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the following unbalanced binary tree for testing 0 / \ / \ 0 0
|
||||
* / / \ / / \ 0 0 0 / \ / \ 0 0 / / 0
|
||||
*/
|
||||
private BinaryTree buildUnbalancedTree() {
|
||||
BinaryTree tree = new BinaryTree();
|
||||
tree.root = new BTNode(0);
|
||||
|
||||
BTNode root = tree.root;
|
||||
root.left = new BTNode(0);
|
||||
root.right = new BTNode(0);
|
||||
|
||||
BTNode left = root.left;
|
||||
BTNode right = root.right;
|
||||
|
||||
left.left = new BTNode(0);
|
||||
right.left = new BTNode(0);
|
||||
right.right = new BTNode(0);
|
||||
right.left.right = new BTNode(0);
|
||||
|
||||
left = left.left;
|
||||
left.left = new BTNode(0);
|
||||
left.left.left = new BTNode(0);
|
||||
left.left.left.left = new BTNode(0);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the following balanced binary tree for testing 0 / \ / \ 0 0 /
|
||||
* \ / \ / 0 / \ 0 0 0 / / / / 0 0
|
||||
*/
|
||||
private BinaryTree buildBalancedTree() {
|
||||
BinaryTree tree = new BinaryTree();
|
||||
tree.root = new BTNode(0);
|
||||
|
||||
BTNode root = tree.root;
|
||||
root.left = new BTNode(0);
|
||||
root.right = new BTNode(0);
|
||||
|
||||
BTNode left = root.left;
|
||||
BTNode right = root.right;
|
||||
|
||||
left.left = new BTNode(0);
|
||||
left.right = new BTNode(0);
|
||||
right.left = new BTNode(0);
|
||||
right.right = new BTNode(0);
|
||||
|
||||
right.right.left = new BTNode(0);
|
||||
|
||||
left.left.left = new BTNode(0);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// We create a new object to check the binary trees for balance
|
||||
CheckIfBinaryTreeBalanced balanceCheck = new CheckIfBinaryTreeBalanced();
|
||||
|
||||
// Build a balanced and unbalanced binary tree
|
||||
BinaryTree balancedTree = balanceCheck.buildBalancedTree();
|
||||
BinaryTree unbalancedTree = balanceCheck.buildUnbalancedTree();
|
||||
|
||||
// Run basic tests on the algorithms to check for balance
|
||||
boolean isBalancedRB = balanceCheck.isBalancedRecursive(balancedTree); // true
|
||||
boolean isBalancedRU = balanceCheck.isBalancedRecursive(unbalancedTree); // false
|
||||
boolean isBalancedIB = balanceCheck.isBalancedIterative(balancedTree); // true
|
||||
boolean isBalancedIU = balanceCheck.isBalancedIterative(unbalancedTree); // false
|
||||
|
||||
// Print the results
|
||||
System.out.println("isBalancedRB: " + isBalancedRB);
|
||||
System.out.println("isBalancedRU: " + isBalancedRU);
|
||||
System.out.println("isBalancedIB: " + isBalancedIB);
|
||||
System.out.println("isBalancedIU: " + isBalancedIU);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import com.thealgorithms.datastructures.trees.BinaryTree.Node;
|
||||
|
||||
/**
|
||||
* Given a sorted array. Create a balanced binary search tree from it.
|
||||
*
|
||||
* Steps: 1. Find the middle element of array. This will act as root 2. Use the
|
||||
* left half recursively to create left subtree 3. Use the right half
|
||||
* recursively to create right subtree
|
||||
*/
|
||||
public class CreateBSTFromSortedArray {
|
||||
|
||||
public static void main(String[] args) {
|
||||
test(new int[]{});
|
||||
test(new int[]{1, 2, 3});
|
||||
test(new int[]{1, 2, 3, 4, 5});
|
||||
test(new int[]{1, 2, 3, 4, 5, 6, 7});
|
||||
}
|
||||
|
||||
private static void test(int[] array) {
|
||||
BinaryTree root = new BinaryTree(createBst(array, 0, array.length - 1));
|
||||
System.out.println("\n\nPreorder Traversal: ");
|
||||
root.preOrder(root.getRoot());
|
||||
System.out.println("\nInorder Traversal: ");
|
||||
root.inOrder(root.getRoot());
|
||||
System.out.println("\nPostOrder Traversal: ");
|
||||
root.postOrder(root.getRoot());
|
||||
}
|
||||
|
||||
private static Node createBst(int[] array, int start, int end) {
|
||||
// No element left.
|
||||
if (start > end) {
|
||||
return null;
|
||||
}
|
||||
int mid = start + (end - start) / 2;
|
||||
|
||||
// middle element will be the root
|
||||
Node root = new Node(array[mid]);
|
||||
root.left = createBst(array, start, mid - 1);
|
||||
root.right = createBst(array, mid + 1, end);
|
||||
return root;
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.thealgorithms.datastructures.trees.BinaryTree.Node;
|
||||
|
||||
/**
|
||||
* Approach: Naive Solution: Create root node from first value present in
|
||||
* preorder traversal. Look for the index of root node's value in inorder
|
||||
* traversal. That will tell total nodes present in left subtree and right
|
||||
* subtree. Based on that index create left and right subtree. Complexity: Time:
|
||||
* O(n^2) for each node there is iteration to find index in inorder array Space:
|
||||
* Stack size = O(height) = O(lg(n))
|
||||
*
|
||||
* Optimized Solution: Instead of iterating over inorder array to find index of
|
||||
* root value, create a hashmap and find out the index of root value.
|
||||
* Complexity: Time: O(n) hashmap reduced iteration to find index in inorder
|
||||
* array Space: O(n) space taken by hashmap
|
||||
*
|
||||
*/
|
||||
public class CreateBinaryTreeFromInorderPreorder {
|
||||
|
||||
public static void main(String[] args) {
|
||||
test(new Integer[]{}, new Integer[]{}); // empty tree
|
||||
test(new Integer[]{1}, new Integer[]{1}); // single node tree
|
||||
test(new Integer[]{1, 2, 3, 4}, new Integer[]{1, 2, 3, 4}); // right skewed tree
|
||||
test(new Integer[]{1, 2, 3, 4}, new Integer[]{4, 3, 2, 1}); // left skewed tree
|
||||
test(new Integer[]{3, 9, 20, 15, 7}, new Integer[]{9, 3, 15, 20, 7}); // normal tree
|
||||
}
|
||||
|
||||
private static void test(final Integer[] preorder, final Integer[] inorder) {
|
||||
System.out.println("\n====================================================");
|
||||
System.out.println("Naive Solution...");
|
||||
BinaryTree root = new BinaryTree(createTree(preorder, inorder, 0, 0, inorder.length));
|
||||
System.out.println("Preorder Traversal: ");
|
||||
root.preOrder(root.getRoot());
|
||||
System.out.println("\nInorder Traversal: ");
|
||||
root.inOrder(root.getRoot());
|
||||
System.out.println("\nPostOrder Traversal: ");
|
||||
root.postOrder(root.getRoot());
|
||||
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
for (int i = 0; i < inorder.length; i++) {
|
||||
map.put(inorder[i], i);
|
||||
}
|
||||
BinaryTree optimizedRoot = new BinaryTree(createTreeOptimized(preorder, inorder, 0, 0, inorder.length, map));
|
||||
System.out.println("\n\nOptimized solution...");
|
||||
System.out.println("Preorder Traversal: ");
|
||||
optimizedRoot.preOrder(root.getRoot());
|
||||
System.out.println("\nInorder Traversal: ");
|
||||
optimizedRoot.inOrder(root.getRoot());
|
||||
System.out.println("\nPostOrder Traversal: ");
|
||||
optimizedRoot.postOrder(root.getRoot());
|
||||
}
|
||||
|
||||
private static Node createTree(final Integer[] preorder, final Integer[] inorder,
|
||||
final int preStart, final int inStart, final int size) {
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Node root = new Node(preorder[preStart]);
|
||||
int i = inStart;
|
||||
while (preorder[preStart] != inorder[i]) {
|
||||
i++;
|
||||
}
|
||||
int leftNodesCount = i - inStart;
|
||||
int rightNodesCount = size - leftNodesCount - 1;
|
||||
root.left = createTree(preorder, inorder, preStart + 1, inStart, leftNodesCount);
|
||||
root.right = createTree(preorder, inorder, preStart + leftNodesCount + 1, i + 1,
|
||||
rightNodesCount);
|
||||
return root;
|
||||
|
||||
}
|
||||
|
||||
private static Node createTreeOptimized(final Integer[] preorder, final Integer[] inorder,
|
||||
final int preStart, final int inStart, final int size,
|
||||
final Map<Integer, Integer> inorderMap) {
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Node root = new Node(preorder[preStart]);
|
||||
int i = inorderMap.get(preorder[preStart]);
|
||||
int leftNodesCount = i - inStart;
|
||||
int rightNodesCount = size - leftNodesCount - 1;
|
||||
root.left = createTreeOptimized(preorder, inorder, preStart + 1, inStart,
|
||||
leftNodesCount, inorderMap);
|
||||
root.right = createTreeOptimized(preorder, inorder, preStart + leftNodesCount + 1,
|
||||
i + 1, rightNodesCount, inorderMap);
|
||||
return root;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
public class FenwickTree {
|
||||
|
||||
private int n;
|
||||
private int fen_t[];
|
||||
|
||||
/* Constructor which takes the size of the array as a parameter */
|
||||
public FenwickTree(int n) {
|
||||
this.n = n;
|
||||
this.fen_t = new int[n + 1];
|
||||
}
|
||||
|
||||
/* A function which will add the element val at index i*/
|
||||
public void update(int i, int val) {
|
||||
// As index starts from 0, increment the index by 1
|
||||
i += 1;
|
||||
while (i <= n) {
|
||||
fen_t[i] += val;
|
||||
i += i & (-i);
|
||||
}
|
||||
}
|
||||
|
||||
/* A function which will return the cumulative sum from index 1 to index i*/
|
||||
public int query(int i) {
|
||||
// As index starts from 0, increment the index by 1
|
||||
i += 1;
|
||||
int cumSum = 0;
|
||||
while (i > 0) {
|
||||
cumSum += fen_t[i];
|
||||
i -= i & (-i);
|
||||
}
|
||||
return cumSum;
|
||||
}
|
||||
}
|
@ -0,0 +1,242 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* A generic tree is a tree which can have as many children as it can be It
|
||||
* might be possible that every node present is directly connected to root node.
|
||||
*
|
||||
* <p>
|
||||
* In this code Every function has two copies: one function is helper function
|
||||
* which can be called from main and from that function a private function is
|
||||
* called which will do the actual work. I have done this, while calling from
|
||||
* main one have to give minimum parameters.
|
||||
*/
|
||||
public class GenericTree {
|
||||
|
||||
private class Node {
|
||||
|
||||
int data;
|
||||
ArrayList<Node> child = new ArrayList<>();
|
||||
}
|
||||
|
||||
private Node root;
|
||||
private int size;
|
||||
|
||||
public GenericTree() { // Constructor
|
||||
Scanner scn = new Scanner(System.in);
|
||||
root = create_treeG(null, 0, scn);
|
||||
}
|
||||
|
||||
private Node create_treeG(Node node, int childindx, Scanner scn) {
|
||||
// display
|
||||
if (node == null) {
|
||||
System.out.println("Enter root's data");
|
||||
} else {
|
||||
System.out.println("Enter data of parent of index " + node.data + " " + childindx);
|
||||
}
|
||||
// input
|
||||
node = new Node();
|
||||
node.data = scn.nextInt();
|
||||
System.out.println("number of children");
|
||||
int number = scn.nextInt();
|
||||
for (int i = 0; i < number; i++) {
|
||||
Node child = create_treeG(node, i, scn);
|
||||
size++;
|
||||
node.child.add(child);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to display the generic tree
|
||||
*/
|
||||
public void display() { // Helper function
|
||||
display_1(root);
|
||||
}
|
||||
|
||||
private void display_1(Node parent) {
|
||||
System.out.print(parent.data + "=>");
|
||||
for (int i = 0; i < parent.child.size(); i++) {
|
||||
System.out.print(parent.child.get(i).data + " ");
|
||||
}
|
||||
System.out.println(".");
|
||||
for (int i = 0; i < parent.child.size(); i++) {
|
||||
display_1(parent.child.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* One call store the size directly but if you are asked compute size this
|
||||
* function to calculate size goes as follows
|
||||
*
|
||||
* @return size
|
||||
*/
|
||||
public int size2call() {
|
||||
return size2(root);
|
||||
}
|
||||
|
||||
public int size2(Node roott) {
|
||||
int sz = 0;
|
||||
for (int i = 0; i < roott.child.size(); i++) {
|
||||
sz += size2(roott.child.get(i));
|
||||
}
|
||||
return sz + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute maximum value in the generic tree
|
||||
*
|
||||
* @return maximum value
|
||||
*/
|
||||
public int maxcall() {
|
||||
int maxi = root.data;
|
||||
return max(root, maxi);
|
||||
}
|
||||
|
||||
private int max(Node roott, int maxi) {
|
||||
if (maxi < roott.data) {
|
||||
maxi = roott.data;
|
||||
}
|
||||
for (int i = 0; i < roott.child.size(); i++) {
|
||||
maxi = max(roott.child.get(i), maxi);
|
||||
}
|
||||
|
||||
return maxi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute HEIGHT of the generic tree
|
||||
*
|
||||
* @return height
|
||||
*/
|
||||
public int heightcall() {
|
||||
return height(root) - 1;
|
||||
}
|
||||
|
||||
private int height(Node node) {
|
||||
int h = 0;
|
||||
for (int i = 0; i < node.child.size(); i++) {
|
||||
int k = height(node.child.get(i));
|
||||
if (k > h) {
|
||||
h = k;
|
||||
}
|
||||
}
|
||||
return h + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to find whether a number is present in the generic tree or not
|
||||
*
|
||||
* @param info number
|
||||
* @return present or not
|
||||
*/
|
||||
public boolean findcall(int info) {
|
||||
return find(root, info);
|
||||
}
|
||||
|
||||
private boolean find(Node node, int info) {
|
||||
if (node.data == info) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < node.child.size(); i++) {
|
||||
if (find(node.child.get(i), info)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to calculate depth of generic tree
|
||||
*
|
||||
* @param dep depth
|
||||
*/
|
||||
public void depthcaller(int dep) {
|
||||
depth(root, dep);
|
||||
}
|
||||
|
||||
public void depth(Node node, int dep) {
|
||||
if (dep == 0) {
|
||||
System.out.println(node.data);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < node.child.size(); i++) {
|
||||
depth(node.child.get(i), dep - 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to print generic tree in pre-order
|
||||
*/
|
||||
public void preordercall() {
|
||||
preorder(root);
|
||||
System.out.println(".");
|
||||
}
|
||||
|
||||
private void preorder(Node node) {
|
||||
System.out.print(node.data + " ");
|
||||
for (int i = 0; i < node.child.size(); i++) {
|
||||
preorder(node.child.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to print generic tree in post-order
|
||||
*/
|
||||
public void postordercall() {
|
||||
postorder(root);
|
||||
System.out.println(".");
|
||||
}
|
||||
|
||||
private void postorder(Node node) {
|
||||
for (int i = 0; i < node.child.size(); i++) {
|
||||
postorder(node.child.get(i));
|
||||
}
|
||||
System.out.print(node.data + " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to print generic tree in level-order
|
||||
*/
|
||||
public void levelorder() {
|
||||
LinkedList<Node> q = new LinkedList<>();
|
||||
q.addLast(root);
|
||||
while (!q.isEmpty()) {
|
||||
int k = q.getFirst().data;
|
||||
System.out.print(k + " ");
|
||||
|
||||
for (int i = 0; i < q.getFirst().child.size(); i++) {
|
||||
q.addLast(q.getFirst().child.get(i));
|
||||
}
|
||||
q.removeFirst();
|
||||
}
|
||||
System.out.println(".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to remove all leaves of generic tree
|
||||
*/
|
||||
public void removeleavescall() {
|
||||
removeleaves(root);
|
||||
}
|
||||
|
||||
private void removeleaves(Node node) {
|
||||
ArrayList<Integer> arr = new ArrayList<>();
|
||||
for (int i = 0; i < node.child.size(); i++) {
|
||||
if (node.child.get(i).child.size() == 0) {
|
||||
arr.add(i);
|
||||
// node.child.remove(i);
|
||||
// i--;
|
||||
} else {
|
||||
removeleaves(node.child.get(i));
|
||||
}
|
||||
}
|
||||
for (int i = arr.size() - 1; i >= 0; i--) {
|
||||
node.child.remove(arr.get(i) + 0);
|
||||
}
|
||||
}
|
||||
}
|
113
src/main/java/com/thealgorithms/datastructures/trees/LCA.java
Normal file
113
src/main/java/com/thealgorithms/datastructures/trees/LCA.java
Normal file
@ -0,0 +1,113 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class LCA {
|
||||
|
||||
private static Scanner scanner = new Scanner(System.in);
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
//The adjacency list representation of a tree:
|
||||
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
|
||||
|
||||
//v is the number of vertices and e is the number of edges
|
||||
int v = scanner.nextInt(), e = v - 1;
|
||||
|
||||
for (int i = 0; i < v; i++) {
|
||||
adj.add(new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
//Storing the given tree as an adjacency list
|
||||
int to, from;
|
||||
for (int i = 0; i < e; i++) {
|
||||
|
||||
to = scanner.nextInt();
|
||||
from = scanner.nextInt();
|
||||
|
||||
adj.get(to).add(from);
|
||||
adj.get(from).add(to);
|
||||
}
|
||||
|
||||
//parent[v1] gives parent of a vertex v1
|
||||
int[] parent = new int[v];
|
||||
|
||||
//depth[v1] gives depth of vertex v1 with respect to the root
|
||||
int[] depth = new int[v];
|
||||
|
||||
//Assuming the tree to be rooted at 0, hence calculating parent and depth of every vertex
|
||||
dfs(adj, 0, -1, parent, depth);
|
||||
|
||||
//Inputting the two vertices whose LCA is to be calculated
|
||||
int v1 = scanner.nextInt(), v2 = scanner.nextInt();
|
||||
|
||||
//Outputting the LCA
|
||||
System.out.println(getLCA(v1, v2, depth, parent));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Depth first search to calculate parent and depth of every vertex
|
||||
*
|
||||
* @param adj The adjacency list representation of the tree
|
||||
* @param s The source vertex
|
||||
* @param p Parent of source
|
||||
* @param parent An array to store parents of all vertices
|
||||
* @param depth An array to store depth of all vertices
|
||||
*/
|
||||
private static void dfs(ArrayList<ArrayList<Integer>> adj, int s, int p, int[] parent, int[] depth) {
|
||||
for (int adjacent : adj.get(s)) {
|
||||
if (adjacent != p) {
|
||||
parent[adjacent] = s;
|
||||
depth[adjacent] = 1 + depth[s];
|
||||
dfs(adj, adjacent, s, parent, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to calculate Lowest Common Ancestor
|
||||
*
|
||||
* @param v1 The first vertex
|
||||
* @param v2 The second vertex
|
||||
* @param depth An array with depths of all vertices
|
||||
* @param parent An array with parents of all vertices
|
||||
* @return Returns a vertex that is LCA of v1 and v2
|
||||
*/
|
||||
private static int getLCA(int v1, int v2, int[] depth, int[] parent) {
|
||||
if (depth[v1] < depth[v2]) {
|
||||
int temp = v1;
|
||||
v1 = v2;
|
||||
v2 = temp;
|
||||
}
|
||||
while (depth[v1] != depth[v2]) {
|
||||
v1 = parent[v1];
|
||||
}
|
||||
if (v1 == v2) {
|
||||
return v1;
|
||||
}
|
||||
while (v1 != v2) {
|
||||
v1 = parent[v1];
|
||||
v2 = parent[v2];
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Input:
|
||||
* 10
|
||||
* 0 1
|
||||
* 0 2
|
||||
* 1 5
|
||||
* 5 6
|
||||
* 2 4
|
||||
* 2 3
|
||||
* 3 7
|
||||
* 7 9
|
||||
* 7 8
|
||||
* 9 4
|
||||
* Output:
|
||||
* 2
|
||||
*/
|
@ -0,0 +1,58 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
public class LevelOrderTraversal {
|
||||
|
||||
class Node {
|
||||
|
||||
int data;
|
||||
Node left, right;
|
||||
|
||||
public Node(int item) {
|
||||
data = item;
|
||||
left = right = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Root of the Binary Tree
|
||||
Node root;
|
||||
|
||||
public LevelOrderTraversal(Node root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/* function to print level order traversal of tree*/
|
||||
void printLevelOrder() {
|
||||
int h = height(root);
|
||||
int i;
|
||||
for (i = 1; i <= h; i++) {
|
||||
printGivenLevel(root, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the "height" of a tree -- the number of
|
||||
nodes along the longest path from the root node
|
||||
down to the farthest leaf node.*/
|
||||
int height(Node root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
} else {
|
||||
/**
|
||||
* Return the height of larger subtree
|
||||
*/
|
||||
return Math.max(height(root.left), height(root.right)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print nodes at the given level */
|
||||
void printGivenLevel(Node root, int level) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
if (level == 1) {
|
||||
System.out.print(root.data + " ");
|
||||
} else if (level > 1) {
|
||||
printGivenLevel(root.left, level - 1);
|
||||
printGivenLevel(root.right, level - 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/* Class to print Level Order Traversal */
|
||||
public class LevelOrderTraversalQueue {
|
||||
|
||||
/* Class to represent Tree node */
|
||||
class Node {
|
||||
|
||||
int data;
|
||||
Node left, right;
|
||||
|
||||
public Node(int item) {
|
||||
data = item;
|
||||
left = null;
|
||||
right = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a binary tree. Print its nodes in level order
|
||||
using array for implementing queue */
|
||||
void printLevelOrder(Node root) {
|
||||
Queue<Node> queue = new LinkedList<Node>();
|
||||
queue.add(root);
|
||||
while (!queue.isEmpty()) {
|
||||
|
||||
/* poll() removes the present head.
|
||||
For more information on poll() visit
|
||||
http://www.tutorialspoint.com/java/util/linkedlist_poll.htm */
|
||||
Node tempNode = queue.poll();
|
||||
System.out.print(tempNode.data + " ");
|
||||
|
||||
/*Enqueue left child */
|
||||
if (tempNode.left != null) {
|
||||
queue.add(tempNode.left);
|
||||
}
|
||||
|
||||
/*Enqueue right child */
|
||||
if (tempNode.right != null) {
|
||||
queue.add(tempNode.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package com.thealgorithms.datastructures.trees; // Java program to print top view of Binary tree
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
// Class for a tree node
|
||||
class TreeNode {
|
||||
// Members
|
||||
|
||||
int key;
|
||||
TreeNode left, right;
|
||||
|
||||
// Constructor
|
||||
public TreeNode(int key) {
|
||||
this.key = key;
|
||||
left = right = null;
|
||||
}
|
||||
}
|
||||
|
||||
// A class to represent a queue item. The queue is used to do Level
|
||||
// order traversal. Every Queue item contains node and horizontal
|
||||
// distance of node from root
|
||||
class QItem {
|
||||
|
||||
TreeNode node;
|
||||
int hd;
|
||||
|
||||
public QItem(TreeNode n, int h) {
|
||||
node = n;
|
||||
hd = h;
|
||||
}
|
||||
}
|
||||
|
||||
// Class for a Binary Tree
|
||||
class Tree {
|
||||
|
||||
TreeNode root;
|
||||
|
||||
// Constructors
|
||||
public Tree() {
|
||||
root = null;
|
||||
}
|
||||
|
||||
public Tree(TreeNode n) {
|
||||
root = n;
|
||||
}
|
||||
|
||||
// This method prints nodes in top view of binary tree
|
||||
public void printTopView() {
|
||||
// base case
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Creates an empty hashset
|
||||
HashSet<Integer> set = new HashSet<>();
|
||||
|
||||
// Create a queue and add root to it
|
||||
Queue<QItem> Q = new LinkedList<QItem>();
|
||||
Q.add(new QItem(root, 0)); // Horizontal distance of root is 0
|
||||
|
||||
// Standard BFS or level order traversal loop
|
||||
while (!Q.isEmpty()) {
|
||||
// Remove the front item and get its details
|
||||
QItem qi = Q.remove();
|
||||
int hd = qi.hd;
|
||||
TreeNode n = qi.node;
|
||||
|
||||
// If this is the first node at its horizontal distance,
|
||||
// then this node is in top view
|
||||
if (!set.contains(hd)) {
|
||||
set.add(hd);
|
||||
System.out.print(n.key + " ");
|
||||
}
|
||||
|
||||
// Enqueue left and right children of current node
|
||||
if (n.left != null) {
|
||||
Q.add(new QItem(n.left, hd - 1));
|
||||
}
|
||||
if (n.right != null) {
|
||||
Q.add(new QItem(n.right, hd + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Driver class to test above methods
|
||||
public class PrintTopViewofTree {
|
||||
|
||||
public static void main(String[] args) {
|
||||
/* Create following Binary Tree
|
||||
1
|
||||
/ \
|
||||
2 3
|
||||
\
|
||||
4
|
||||
\
|
||||
5
|
||||
\
|
||||
6*/
|
||||
TreeNode root = new TreeNode(1);
|
||||
root.left = new TreeNode(2);
|
||||
root.right = new TreeNode(3);
|
||||
root.left.right = new TreeNode(4);
|
||||
root.left.right.right = new TreeNode(5);
|
||||
root.left.right.right.right = new TreeNode(6);
|
||||
Tree t = new Tree(root);
|
||||
System.out.println("Following are nodes in top view of Binary Tree");
|
||||
t.printTopView();
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
## Tree
|
||||
### Description
|
||||
|
||||
Tree is a data structure where the data is organized in a hierarchial structure. There should be one root node (which does not have any parent) and all subsequent nodes are represented as children of the root node and its children. If a node has at least one child, it is called `internal` node and nodes with no children are called `leaf` nodes.
|
||||
|
||||
### Basic Structure
|
||||
|
||||
```
|
||||
class Tree<E>{
|
||||
E value;
|
||||
Tree left;
|
||||
Tree right;
|
||||
}
|
||||
```
|
||||
|
||||
This basic structure is for a binary tree where each internal tree has at least one and at most two children. `left` and `right` represent the two children and `value` is the placeholder for data.
|
||||
|
||||
|
||||
### Properties
|
||||
1. Tree data structure gives the facility to organize data in a hierarchial structure
|
||||
2. Tree nodes can be inserted in a sorted order which can be used for searching and inserting data in O(logN) time where N is the number of nodes.
|
||||
|
||||
### Types of Trees
|
||||
1. **Binary Search Tree:** A binary tree where the elements are inserted in asorted order. Here the searching can be done in O(logN) time in (depending on the structure)
|
||||
2. **AVL Tree and Red-Black Tree:** Binary search trees where the height is balanced. Here, searching is guaranteed to be in O(logN) time.
|
||||
3. **Traversal algorithms:** <br>
|
||||
a. **BFS:** Breadth-first-search where all the children at each level are traversed at once. <br>
|
||||
b. **DFS:** Depth-first-search where the first discovered child is traversed first.
|
||||
4. **MultiWay Search Tree:** Tree in sorted order, but more than two children in each internal node.
|
||||
5. **Trie:** A character based multiway search tree where words can be retrieved based on their prefix. Useful for implementing prefix based search algorithm.
|
@ -0,0 +1,340 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @author jack870131
|
||||
*/
|
||||
public class RedBlackBST {
|
||||
|
||||
private final int R = 0;
|
||||
private final int B = 1;
|
||||
|
||||
private class Node {
|
||||
|
||||
int key = -1, color = B;
|
||||
Node left = nil, right = nil, p = nil;
|
||||
|
||||
Node(int key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
private final Node nil = new Node(-1);
|
||||
private Node root = nil;
|
||||
|
||||
public void printTree(Node node) {
|
||||
if (node == nil) {
|
||||
return;
|
||||
}
|
||||
printTree(node.left);
|
||||
System.out.print(
|
||||
((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n");
|
||||
printTree(node.right);
|
||||
}
|
||||
|
||||
public void printTreepre(Node node) {
|
||||
if (node == nil) {
|
||||
return;
|
||||
}
|
||||
System.out.print(
|
||||
((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n");
|
||||
printTree(node.left);
|
||||
printTree(node.right);
|
||||
}
|
||||
|
||||
private Node findNode(Node findNode, Node node) {
|
||||
if (root == nil) {
|
||||
return null;
|
||||
}
|
||||
if (findNode.key < node.key) {
|
||||
if (node.left != nil) {
|
||||
return findNode(findNode, node.left);
|
||||
}
|
||||
} else if (findNode.key > node.key) {
|
||||
if (node.right != nil) {
|
||||
return findNode(findNode, node.right);
|
||||
}
|
||||
} else if (findNode.key == node.key) {
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void insert(Node node) {
|
||||
Node temp = root;
|
||||
if (root == nil) {
|
||||
root = node;
|
||||
node.color = B;
|
||||
node.p = nil;
|
||||
} else {
|
||||
node.color = R;
|
||||
while (true) {
|
||||
if (node.key < temp.key) {
|
||||
if (temp.left == nil) {
|
||||
temp.left = node;
|
||||
node.p = temp;
|
||||
break;
|
||||
} else {
|
||||
temp = temp.left;
|
||||
}
|
||||
} else if (node.key >= temp.key) {
|
||||
if (temp.right == nil) {
|
||||
temp.right = node;
|
||||
node.p = temp;
|
||||
break;
|
||||
} else {
|
||||
temp = temp.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
fixTree(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void fixTree(Node node) {
|
||||
while (node.p.color == R) {
|
||||
Node y = nil;
|
||||
if (node.p == node.p.p.left) {
|
||||
y = node.p.p.right;
|
||||
|
||||
if (y != nil && y.color == R) {
|
||||
node.p.color = B;
|
||||
y.color = B;
|
||||
node.p.p.color = R;
|
||||
node = node.p.p;
|
||||
continue;
|
||||
}
|
||||
if (node == node.p.right) {
|
||||
node = node.p;
|
||||
rotateLeft(node);
|
||||
}
|
||||
node.p.color = B;
|
||||
node.p.p.color = R;
|
||||
rotateRight(node.p.p);
|
||||
} else {
|
||||
y = node.p.p.left;
|
||||
if (y != nil && y.color == R) {
|
||||
node.p.color = B;
|
||||
y.color = B;
|
||||
node.p.p.color = R;
|
||||
node = node.p.p;
|
||||
continue;
|
||||
}
|
||||
if (node == node.p.left) {
|
||||
node = node.p;
|
||||
rotateRight(node);
|
||||
}
|
||||
node.p.color = B;
|
||||
node.p.p.color = R;
|
||||
rotateLeft(node.p.p);
|
||||
}
|
||||
}
|
||||
root.color = B;
|
||||
}
|
||||
|
||||
void rotateLeft(Node node) {
|
||||
if (node.p != nil) {
|
||||
if (node == node.p.left) {
|
||||
node.p.left = node.right;
|
||||
} else {
|
||||
node.p.right = node.right;
|
||||
}
|
||||
node.right.p = node.p;
|
||||
node.p = node.right;
|
||||
if (node.right.left != nil) {
|
||||
node.right.left.p = node;
|
||||
}
|
||||
node.right = node.right.left;
|
||||
node.p.left = node;
|
||||
} else {
|
||||
Node right = root.right;
|
||||
root.right = right.left;
|
||||
right.left.p = root;
|
||||
root.p = right;
|
||||
right.left = root;
|
||||
right.p = nil;
|
||||
root = right;
|
||||
}
|
||||
}
|
||||
|
||||
void rotateRight(Node node) {
|
||||
if (node.p != nil) {
|
||||
if (node == node.p.left) {
|
||||
node.p.left = node.left;
|
||||
} else {
|
||||
node.p.right = node.left;
|
||||
}
|
||||
|
||||
node.left.p = node.p;
|
||||
node.p = node.left;
|
||||
if (node.left.right != nil) {
|
||||
node.left.right.p = node;
|
||||
}
|
||||
node.left = node.left.right;
|
||||
node.p.right = node;
|
||||
} else {
|
||||
Node left = root.left;
|
||||
root.left = root.left.right;
|
||||
left.right.p = root;
|
||||
root.p = left;
|
||||
left.right = root;
|
||||
left.p = nil;
|
||||
root = left;
|
||||
}
|
||||
}
|
||||
|
||||
void transplant(Node target, Node with) {
|
||||
if (target.p == nil) {
|
||||
root = with;
|
||||
} else if (target == target.p.left) {
|
||||
target.p.left = with;
|
||||
} else {
|
||||
target.p.right = with;
|
||||
}
|
||||
with.p = target.p;
|
||||
}
|
||||
|
||||
Node treeMinimum(Node subTreeRoot) {
|
||||
while (subTreeRoot.left != nil) {
|
||||
subTreeRoot = subTreeRoot.left;
|
||||
}
|
||||
return subTreeRoot;
|
||||
}
|
||||
|
||||
boolean delete(Node z) {
|
||||
if ((z = findNode(z, root)) == null) {
|
||||
return false;
|
||||
}
|
||||
Node x;
|
||||
Node y = z;
|
||||
int yorigcolor = y.color;
|
||||
|
||||
if (z.left == nil) {
|
||||
x = z.right;
|
||||
transplant(z, z.right);
|
||||
} else if (z.right == nil) {
|
||||
x = z.left;
|
||||
transplant(z, z.left);
|
||||
} else {
|
||||
y = treeMinimum(z.right);
|
||||
yorigcolor = y.color;
|
||||
x = y.right;
|
||||
if (y.p == z) {
|
||||
x.p = y;
|
||||
} else {
|
||||
transplant(y, y.right);
|
||||
y.right = z.right;
|
||||
y.right.p = y;
|
||||
}
|
||||
transplant(z, y);
|
||||
y.left = z.left;
|
||||
y.left.p = y;
|
||||
y.color = z.color;
|
||||
}
|
||||
if (yorigcolor == B) {
|
||||
deleteFixup(x);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void deleteFixup(Node x) {
|
||||
while (x != root && x.color == B) {
|
||||
if (x == x.p.left) {
|
||||
Node w = x.p.right;
|
||||
if (w.color == R) {
|
||||
w.color = B;
|
||||
x.p.color = R;
|
||||
rotateLeft(x.p);
|
||||
w = x.p.right;
|
||||
}
|
||||
if (w.left.color == B && w.right.color == B) {
|
||||
w.color = R;
|
||||
x = x.p;
|
||||
continue;
|
||||
} else if (w.right.color == B) {
|
||||
w.left.color = B;
|
||||
w.color = R;
|
||||
rotateRight(w);
|
||||
w = x.p.right;
|
||||
}
|
||||
if (w.right.color == R) {
|
||||
w.color = x.p.color;
|
||||
x.p.color = B;
|
||||
w.right.color = B;
|
||||
rotateLeft(x.p);
|
||||
x = root;
|
||||
}
|
||||
} else {
|
||||
Node w = x.p.left;
|
||||
if (w.color == R) {
|
||||
w.color = B;
|
||||
x.p.color = R;
|
||||
rotateRight(x.p);
|
||||
w = x.p.left;
|
||||
}
|
||||
if (w.right.color == B && w.left.color == B) {
|
||||
w.color = R;
|
||||
x = x.p;
|
||||
continue;
|
||||
} else if (w.left.color == B) {
|
||||
w.right.color = B;
|
||||
w.color = R;
|
||||
rotateLeft(w);
|
||||
w = x.p.left;
|
||||
}
|
||||
if (w.left.color == R) {
|
||||
w.color = x.p.color;
|
||||
x.p.color = B;
|
||||
w.left.color = B;
|
||||
rotateRight(x.p);
|
||||
x = root;
|
||||
}
|
||||
}
|
||||
}
|
||||
x.color = B;
|
||||
}
|
||||
|
||||
public void insertDemo() {
|
||||
Scanner scan = new Scanner(System.in);
|
||||
while (true) {
|
||||
System.out.println("Add items");
|
||||
|
||||
int item;
|
||||
Node node;
|
||||
|
||||
item = scan.nextInt();
|
||||
while (item != -999) {
|
||||
node = new Node(item);
|
||||
insert(node);
|
||||
item = scan.nextInt();
|
||||
}
|
||||
printTree(root);
|
||||
System.out.println("Pre order");
|
||||
printTreepre(root);
|
||||
break;
|
||||
}
|
||||
scan.close();
|
||||
}
|
||||
|
||||
public void deleteDemo() {
|
||||
Scanner scan = new Scanner(System.in);
|
||||
System.out.println("Delete items");
|
||||
int item;
|
||||
Node node;
|
||||
item = scan.nextInt();
|
||||
node = new Node(item);
|
||||
System.out.print("Deleting item " + item);
|
||||
if (delete(node)) {
|
||||
System.out.print(": deleted!");
|
||||
} else {
|
||||
System.out.print(": does not exist!");
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
printTree(root);
|
||||
System.out.println("Pre order");
|
||||
printTreepre(root);
|
||||
scan.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
public class SegmentTree {
|
||||
|
||||
private int seg_t[];
|
||||
private int n;
|
||||
private int arr[];
|
||||
|
||||
/* Constructor which takes the size of the array and the array as a parameter*/
|
||||
public SegmentTree(int n, int arr[]) {
|
||||
this.n = n;
|
||||
int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));
|
||||
int seg_size = 2 * (int) Math.pow(2, x) - 1;
|
||||
|
||||
this.seg_t = new int[seg_size];
|
||||
this.arr = arr;
|
||||
this.n = n;
|
||||
constructTree(arr, 0, n - 1, 0);
|
||||
}
|
||||
|
||||
/* A function which will create the segment tree*/
|
||||
public int constructTree(int[] arr, int start, int end, int index) {
|
||||
if (start == end) {
|
||||
this.seg_t[index] = arr[start];
|
||||
return arr[start];
|
||||
}
|
||||
|
||||
int mid = start + (end - start) / 2;
|
||||
this.seg_t[index] = constructTree(arr, start, mid, index * 2 + 1)
|
||||
+ constructTree(arr, mid + 1, end, index * 2 + 2);
|
||||
return this.seg_t[index];
|
||||
}
|
||||
|
||||
/* A function which will update the value at a index i. This will be called by the
|
||||
update function internally*/
|
||||
private void updateTree(int start, int end, int index, int diff, int seg_index) {
|
||||
if (index < start || index > end) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.seg_t[seg_index] += diff;
|
||||
if (start != end) {
|
||||
int mid = start + (end - start) / 2;
|
||||
updateTree(start, mid, index, diff, seg_index * 2 + 1);
|
||||
updateTree(mid + 1, end, index, diff, seg_index * 2 + 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* A function to update the value at a particular index*/
|
||||
public void update(int index, int value) {
|
||||
if (index < 0 || index > n) {
|
||||
return;
|
||||
}
|
||||
|
||||
int diff = value - arr[index];
|
||||
arr[index] = value;
|
||||
updateTree(0, n - 1, index, diff, 0);
|
||||
}
|
||||
|
||||
/* A function to get the sum of the elements from index l to index r. This will be called internally*/
|
||||
private int getSumTree(int start, int end, int q_start, int q_end, int seg_index) {
|
||||
if (q_start <= start && q_end >= end) {
|
||||
return this.seg_t[seg_index];
|
||||
}
|
||||
|
||||
if (q_start > end || q_end < start) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mid = start + (end - start) / 2;
|
||||
return getSumTree(start, mid, q_start, q_end, seg_index * 2 + 1) + getSumTree(mid + 1, end, q_start, q_end, seg_index * 2 + 2);
|
||||
}
|
||||
|
||||
/* A function to query the sum of the subarray [start...end]*/
|
||||
public int getSum(int start, int end) {
|
||||
if (start < 0 || end > n || start > end) {
|
||||
return 0;
|
||||
}
|
||||
return getSumTree(0, n - 1, start, end, 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* @author Varun Upadhyay (https://github.com/varunu28)
|
||||
*/
|
||||
// Driver Program
|
||||
public class TreeTraversal {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node tree = new Node(5);
|
||||
tree.insert(3);
|
||||
tree.insert(2);
|
||||
tree.insert(7);
|
||||
tree.insert(4);
|
||||
tree.insert(6);
|
||||
tree.insert(8);
|
||||
|
||||
// Prints 5 3 2 4 7 6 8
|
||||
System.out.println("Pre order traversal:");
|
||||
tree.printPreOrder();
|
||||
System.out.println();
|
||||
// Prints 2 3 4 5 6 7 8
|
||||
System.out.println("In order traversal:");
|
||||
tree.printInOrder();
|
||||
System.out.println();
|
||||
// Prints 2 4 3 6 8 7 5
|
||||
System.out.println("Post order traversal:");
|
||||
tree.printPostOrder();
|
||||
System.out.println();
|
||||
// Prints 5 3 7 2 4 6 8
|
||||
System.out.println("Level order traversal:");
|
||||
tree.printLevelOrder();
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Node class which initializes a Node of a tree Consists of all 4 traversal
|
||||
* methods: printInOrder, printPostOrder, printPreOrder & printLevelOrder
|
||||
* printInOrder: LEFT -> ROOT -> RIGHT printPreOrder: ROOT -> LEFT -> RIGHT
|
||||
* printPostOrder: LEFT -> RIGHT -> ROOT printLevelOrder: Prints by level
|
||||
* (starting at root), from left to right.
|
||||
*/
|
||||
class Node {
|
||||
|
||||
Node left, right;
|
||||
int data;
|
||||
|
||||
public Node(int data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void insert(int value) {
|
||||
if (value < data) {
|
||||
if (left == null) {
|
||||
left = new Node(value);
|
||||
} else {
|
||||
left.insert(value);
|
||||
}
|
||||
} else {
|
||||
if (right == null) {
|
||||
right = new Node(value);
|
||||
} else {
|
||||
right.insert(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printInOrder() {
|
||||
if (left != null) {
|
||||
left.printInOrder();
|
||||
}
|
||||
System.out.print(data + " ");
|
||||
if (right != null) {
|
||||
right.printInOrder();
|
||||
}
|
||||
}
|
||||
|
||||
public void printPreOrder() {
|
||||
System.out.print(data + " ");
|
||||
if (left != null) {
|
||||
left.printPreOrder();
|
||||
}
|
||||
if (right != null) {
|
||||
right.printPreOrder();
|
||||
}
|
||||
}
|
||||
|
||||
public void printPostOrder() {
|
||||
if (left != null) {
|
||||
left.printPostOrder();
|
||||
}
|
||||
if (right != null) {
|
||||
right.printPostOrder();
|
||||
}
|
||||
System.out.print(data + " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* O(n) time algorithm. Uses O(n) space to store nodes in a queue to aid in
|
||||
* traversal.
|
||||
*/
|
||||
public void printLevelOrder() {
|
||||
LinkedList<Node> queue = new LinkedList<>();
|
||||
queue.add(this);
|
||||
while (queue.size() > 0) {
|
||||
Node head = queue.remove();
|
||||
System.out.print(head.data + " ");
|
||||
// Add children of recently-printed node to queue, if they exist.
|
||||
if (head.left != null) {
|
||||
queue.add(head.left);
|
||||
}
|
||||
if (head.right != null) {
|
||||
queue.add(head.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
/**
|
||||
* Trie Data structure implementation without any libraries
|
||||
*
|
||||
* @author Dheeraj Kumar Barnwal (https://github.com/dheeraj92)
|
||||
*/
|
||||
import java.util.Scanner;
|
||||
|
||||
public class TrieImp {
|
||||
|
||||
public class TrieNode {
|
||||
|
||||
TrieNode[] child;
|
||||
boolean end;
|
||||
|
||||
public TrieNode() {
|
||||
child = new TrieNode[26];
|
||||
end = false;
|
||||
}
|
||||
}
|
||||
|
||||
private final TrieNode root;
|
||||
|
||||
public TrieImp() {
|
||||
root = new TrieNode();
|
||||
}
|
||||
|
||||
public void insert(String word) {
|
||||
TrieNode currentNode = root;
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
TrieNode node = currentNode.child[word.charAt(i) - 'a'];
|
||||
if (node == null) {
|
||||
node = new TrieNode();
|
||||
currentNode.child[word.charAt(i) - 'a'] = node;
|
||||
}
|
||||
currentNode = node;
|
||||
}
|
||||
currentNode.end = true;
|
||||
}
|
||||
|
||||
public boolean search(String word) {
|
||||
TrieNode currentNode = root;
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
char ch = word.charAt(i);
|
||||
TrieNode node = currentNode.child[ch - 'a'];
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
currentNode = node;
|
||||
}
|
||||
return currentNode.end;
|
||||
}
|
||||
|
||||
public boolean delete(String word) {
|
||||
TrieNode currentNode = root;
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
char ch = word.charAt(i);
|
||||
TrieNode node = currentNode.child[ch - 'a'];
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
currentNode = node;
|
||||
}
|
||||
if (currentNode.end == true) {
|
||||
currentNode.end = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void sop(String print) {
|
||||
System.out.println(print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Regex to check if word contains only a-z character
|
||||
*/
|
||||
public static boolean isValid(String word) {
|
||||
return word.matches("^[a-z]+$");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TrieImp obj = new TrieImp();
|
||||
String word;
|
||||
@SuppressWarnings("resource")
|
||||
Scanner scan = new Scanner(System.in);
|
||||
sop("string should contain only a-z character for all operation");
|
||||
while (true) {
|
||||
sop("1. Insert\n2. Search\n3. Delete\n4. Quit");
|
||||
try {
|
||||
int t = scan.nextInt();
|
||||
switch (t) {
|
||||
case 1:
|
||||
word = scan.next();
|
||||
if (isValid(word)) {
|
||||
obj.insert(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
word = scan.next();
|
||||
boolean resS = false;
|
||||
if (isValid(word)) {
|
||||
resS = obj.search(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
if (resS) {
|
||||
sop("word found");
|
||||
} else {
|
||||
sop("word not found");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
word = scan.next();
|
||||
boolean resD = false;
|
||||
if (isValid(word)) {
|
||||
resD = obj.delete(word);
|
||||
} else {
|
||||
sop("Invalid string: allowed only a-z");
|
||||
}
|
||||
if (resD) {
|
||||
sop("word got deleted successfully");
|
||||
} else {
|
||||
sop("word not found");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
sop("Quit successfully");
|
||||
System.exit(1);
|
||||
break;
|
||||
default:
|
||||
sop("Input int from 1-4");
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String badInput = scan.next();
|
||||
sop("This is bad input: " + badInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
public class ValidBSTOrNot {
|
||||
|
||||
class Node {
|
||||
|
||||
int data;
|
||||
Node left, right;
|
||||
|
||||
public Node(int item) {
|
||||
data = item;
|
||||
left = right = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Root of the Binary Tree
|
||||
|
||||
/* can give min and max value according to your code or
|
||||
can write a function to find min and max value of tree. */
|
||||
|
||||
/* returns true if given search tree is binary
|
||||
search tree (efficient version) */
|
||||
boolean isBST(Node root) {
|
||||
return isBSTUtil(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/* Returns true if the given tree is a BST and its
|
||||
values are >= min and <= max. */
|
||||
boolean isBSTUtil(Node node, int min, int max) {
|
||||
/* an empty tree is BST */
|
||||
if (node == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* false if this node violates the min/max constraints */
|
||||
if (node.data < min || node.data > max) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* otherwise check the subtrees recursively
|
||||
tightening the min/max constraints */
|
||||
// Allow only distinct values
|
||||
return (isBSTUtil(node.left, min, node.data - 1) && isBSTUtil(node.right, node.data + 1, max));
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
/* The following class implements a vertical order traversal
|
||||
in a tree from top to bottom and left to right, so for a tree :
|
||||
1
|
||||
/ \
|
||||
2 3
|
||||
/ \ \
|
||||
4 5 6
|
||||
\ / \
|
||||
7 8 10
|
||||
\
|
||||
9
|
||||
the sequence will be :
|
||||
4 2 7 1 5 9 3 8 6 10
|
||||
*/
|
||||
public class VerticalOrderTraversal {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BinaryTree tree = new BinaryTree();
|
||||
tree.put(5);
|
||||
tree.put(6);
|
||||
tree.put(3);
|
||||
tree.put(1);
|
||||
tree.put(4);
|
||||
BinaryTree.Node root = tree.getRoot();
|
||||
ArrayList<Integer> ans = verticalTraversal(root);
|
||||
for (int i : ans) {
|
||||
System.out.print(i + " ");
|
||||
}
|
||||
}
|
||||
|
||||
/*Function that receives a root Node and prints the tree
|
||||
in Vertical Order.*/
|
||||
private static ArrayList<Integer> verticalTraversal(BinaryTree.Node root) {
|
||||
/*Queue to store the Nodes.*/
|
||||
Queue<BinaryTree.Node> queue = new LinkedList<>();
|
||||
|
||||
/*Queue to store the index of particular vertical
|
||||
column of a tree , with root at 0, Nodes on left
|
||||
with negative index and Nodes on right with positive
|
||||
index. */
|
||||
Queue<Integer> index = new LinkedList<>();
|
||||
|
||||
/*Map of Integer and ArrayList to store all the
|
||||
elements in a particular index in a single arrayList
|
||||
that will have a key equal to the index itself. */
|
||||
Map<Integer, ArrayList<Integer>> map = new HashMap<>();
|
||||
|
||||
/* min and max stores leftmost and right most index to
|
||||
later print the tree in vertical fashion.*/
|
||||
int max = 0, min = 0;
|
||||
queue.offer(root);
|
||||
index.offer(0);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
|
||||
if (queue.peek().left != null) {
|
||||
/*Adding the left Node if it is not null
|
||||
and its index by subtracting 1 from it's
|
||||
parent's index*/
|
||||
queue.offer(queue.peek().left);
|
||||
index.offer(index.peek() - 1);
|
||||
}
|
||||
if (queue.peek().right != null) {
|
||||
/*Adding the right Node if it is not null
|
||||
and its index by adding 1 from it's
|
||||
parent's index*/
|
||||
queue.offer(queue.peek().right);
|
||||
index.offer(index.peek() + 1);
|
||||
}
|
||||
/*If the map does not contains the index a new
|
||||
ArrayList is created with the index as key.*/
|
||||
if (!map.containsKey(index.peek())) {
|
||||
ArrayList<Integer> a = new ArrayList<>();
|
||||
map.put(index.peek(), a);
|
||||
}
|
||||
/*For a index, corresponding Node data is added
|
||||
to the respective ArrayList present at that
|
||||
index. */
|
||||
map.get(index.peek()).add(queue.peek().data);
|
||||
max = (int) Math.max(max, index.peek());
|
||||
min = (int) Math.min(min, index.peek());
|
||||
/*The Node and its index are removed
|
||||
from their respective queues.*/
|
||||
index.poll();
|
||||
queue.poll();
|
||||
}
|
||||
/*Finally map data is printed here which has keys
|
||||
from min to max. Each ArrayList represents a
|
||||
vertical column that is added in ans ArrayList.*/
|
||||
ArrayList<Integer> ans = new ArrayList<>();
|
||||
for (int i = min; i <= max; i++) {
|
||||
for (int j = 0; j < map.get(i).size(); j++) {
|
||||
ans.add(map.get(i).get(j));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
NRKTree root = BuildTree();
|
||||
Scanner sc = new Scanner(System.in);
|
||||
System.out.print("Enter first number: ");
|
||||
int inputX0 = sc.nextInt();
|
||||
int toPrint = nearestRightKey(root, inputX0);
|
||||
System.out.println("Key: " + toPrint);
|
||||
}
|
||||
|
||||
public static NRKTree BuildTree() {
|
||||
int randomX = ThreadLocalRandom.current().nextInt(0, 100 + 1);
|
||||
NRKTree root = new NRKTree(null, null, randomX);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
randomX = ThreadLocalRandom.current().nextInt(0, 100 + 1);
|
||||
root = root.insertKey(root, randomX);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static int nearestRightKey(NRKTree root, int x0) {
|
||||
//Check whether tree is empty
|
||||
if (root == null) {
|
||||
return 0;
|
||||
} else {
|
||||
if (root.data - x0 > 0) {
|
||||
// Go left
|
||||
int temp = nearestRightKey(root.left, x0);
|
||||
if (temp == 0) {
|
||||
return root.data;
|
||||
}
|
||||
return temp;
|
||||
} else {
|
||||
// Go right
|
||||
return nearestRightKey(root.right, x0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NRKTree {
|
||||
|
||||
public NRKTree left;
|
||||
public NRKTree right;
|
||||
public int data;
|
||||
|
||||
public NRKTree(int x) {
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
this.data = x;
|
||||
}
|
||||
|
||||
public NRKTree(NRKTree right, NRKTree left, int x) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.data = x;
|
||||
}
|
||||
|
||||
public NRKTree insertKey(NRKTree current, int value) {
|
||||
if (current == null) {
|
||||
return new NRKTree(value);
|
||||
}
|
||||
|
||||
if (value < current.data) {
|
||||
current.left = insertKey(current.left, value);
|
||||
} else if (value > current.data) {
|
||||
current.right = insertKey(current.right, value);
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user