Change project structure to a Maven Java project + Refactor (#2816)

This commit is contained in:
Aitor Fidalgo Sánchez
2021-11-12 07:59:36 +01:00
committed by GitHub
parent 8e533d2617
commit 9fb3364ccc
642 changed files with 26570 additions and 25488 deletions

View 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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

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

View File

@ -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;
}
}

View File

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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

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

View 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
*/

View File

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

View File

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

View File

@ -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();
}
}

View File

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

View File

@ -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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}
}

View File

@ -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;
}
}