I've written a working Binary Search Tree and want to construct some JUnit tests to go along with it. I'm working on three: one to find the maximum value (InOrder traversal), one to remove this maximum value, and one to check if my Binary Tree is balanced. I've written the first two, but can't quite figure out how to nail the last test -- checking for balance. I'd appreciate some guidance, as I feel like I've overlooked something.
My test methods:
public class BSTreePreLabTest {
#Test
public void testFindMax() {
BSTree<Integer> tree = new BSTree<Integer>();
tree.addElement(15);
tree.addElement(16);
tree.addElement(17);
tree.addElement(18);
tree.addElement(19);
tree.addElement(20);
assertEquals("20", tree.findMax().toString());
}
#Test
public void testRemoveMax() {
BSTree<Integer> tree = new BSTree<Integer>();
tree.addElement(15);
tree.addElement(16);
tree.addElement(17);
tree.addElement(18);
tree.addElement(19);
tree.addElement(20);
tree.removeMax();
assertEquals("Inorder traversal: [15, 16, 17, 18, 19]", tree.toString());
}
And my main BinarySearchTree method, for reference, if needed:
public class BSTree<T> {
private BSTreeNode<T> root = null;
private int count;
public BSTree(T element) {
root = new BSTreeNode<T>(element);
count = 1;
}
public BSTree() {
root = null;
count = 0;
}
public void addElement(T element) {
if (isEmpty()) {
root = new BSTreeNode<T>(element);
}
else {
BSTreeNode<T> current = root;
BSTreeNode<T> previous = null;
Comparable<T> comparableElement = (Comparable<T>) element;
while (current != null) {
if (comparableElement.compareTo(current.getElement()) < 0) {
previous = current;
current = current.getLeft();
}
else {
previous = current;
current = current.getRight();
}
}
BSTreeNode<T> newNode = new BSTreeNode<T>(element);
if (comparableElement.compareTo(previous.getElement()) < 0)
previous.setLeft(newNode);
else
previous.setRight(newNode);
}
count++;
}
public boolean isEmpty() {
return root == null;
}
public int size() {
return count;
}
public T find(T targetElement) throws ElementNotFoundException {
BSTreeNode<T> current = findNode(targetElement, root);
if (current == null)
throw new ElementNotFoundException("BSTree");
return (current.getElement());
}
private BSTreeNode<T> findNode(T targetElement, BSTreeNode<T> next) {
if (next == null)
return null;
if (next.getElement().equals(targetElement))
return next;
BSTreeNode<T> temp = findNode(targetElement, next.getLeft());
if (temp == null)
temp = findNode(targetElement, next.getRight());
return temp;
}
public T removeElement(T targetElement) throws ElementNotFoundException {
T result = null;
if (isEmpty())
throw new ElementNotFoundException("BSTree");
else {
BSTreeNode<T> parent = null;
if (((Comparable<T>) targetElement).equals(root.getElement())) {
result = root.getElement();
BSTreeNode<T> temp = replacement(root);
if (temp == null)
root = null;
else {
root.setElement(temp.getElement());
root.setRight(temp.getRight());
root.setLeft(temp.getLeft());
}
} else {
parent = root;
if (((Comparable) targetElement).compareTo(root.getElement()) < 0)
result = removeElement(targetElement, root.getLeft(), parent);
else
result = removeElement(targetElement, root.getRight(), parent);
}
}
count--;
return result;
}
private T removeElement(T targetElement, BSTreeNode<T> node,
BSTreeNode<T> parent) throws ElementNotFoundException {
T result = null;
if (node == null)
throw new ElementNotFoundException("BSTree");
else {
if (((Comparable<T>) targetElement).equals(node.getElement())) {
result = node.getElement();
BSTreeNode<T> temp = replacement(node);
if (parent.getRight() == node)
parent.setRight(temp);
else
parent.setLeft(temp);
} else {
parent = node;
if (((Comparable) targetElement).compareTo(node.getElement()) < 0)
result = removeElement(targetElement, node.getLeft(),
parent);
else
result = removeElement(targetElement, node.getRight(),
parent);
}
}
return result;
}
private BSTreeNode<T> replacement(BSTreeNode<T> node) {
BSTreeNode<T> result = null;
if ((node.getLeft() == null) && (node.getRight() == null))
result = null;
else if ((node.getLeft() != null) && (node.getRight() == null))
result = node.getLeft();
else if ((node.getLeft() == null) && (node.getRight() != null))
result = node.getRight();
else {
BSTreeNode<T> current = node.getRight();
BSTreeNode<T> parent = node;
while (current.getLeft() != null) {
parent = current;
current = current.getLeft();
}
current.setLeft(node.getLeft());
if (node.getRight() != current) {
parent.setLeft(current.getRight());
current.setRight(node.getRight());
}
result = current;
}
return result;
}
public String toString()
{
ArrayList<T> temp = new ArrayList<T>();
inOrder(root, temp);
return "Inorder traversal: " + temp.toString();
}
public Iterator<T> iterator()
{
return iteratorInOrder();
}
public Iterator<T> iteratorInOrder()
{
ArrayList<T> tempList = new ArrayList<T>();
inOrder(root, tempList);
return tempList.iterator();
}
public T findMax(){
T result = null;
if (isEmpty())
throw new ElementNotFoundException ("binary tree");
else {
BSTreeNode<T> current = root;
while (current.getRight() != null)
current = current.getRight();
result = current.getElement();
}
return result;
}
public T removeMax(){
T result = null;
if (isEmpty())
throw new ElementNotFoundException("binary tree");
else
{
if (root.getRight() == null)
{
result = root.getElement();
root = root.getLeft();
}
else
{
BSTreeNode<T> parent = root;
BSTreeNode<T> current = root.getRight();
while (current.getRight() != null)
{
parent = current;
current = current.getRight();
}
result = current.getElement();
parent.setRight(current.getLeft());
}
count--;
}
return result;
}
protected void inOrder(BSTreeNode<T> node, ArrayList<T> tempList) {
if (node != null) {
inOrder(node.getLeft(), tempList);
tempList.add(node.getElement());
inOrder(node.getRight(), tempList);
}
}
}
You can write a function to find the height of left and right sub-tree
int height(Node node)
{
if (node == null)
return 0;
return 1 + Math.max(height(node.left), height(node.right));
}
then, you can write another method to check if the tree is balanced
boolean isBalanced(Node node)
{
int lh;
int rh;
if (node == null)
return true;
lh = height(node.left);
rh = height(node.right);
if (Math.abs(lh - rh) <= 1
&& isBalanced(node.left)
&& isBalanced(node.right)) {
return true;
}
return false;
}
and then, you can write a JUnit test case to test your isBalanced().
I hope this helps!
So I was given an assignment in which I had to find and fix many errors in a somewhat large and sloppy code. I'm down to what looks to be the last one and I can't find the solution to this one. I've read similar scenarios where people get the same mistake but I can't relate them to my code. This is where I get the error: Temp = new BinaryNode(AId,AValue); saying
constructor BinaryNode in class BinaryNode cannot be applied to given
types;
Btree Class
package evidencia2datos;
public class BTree {
private BinaryNode Root;
private int NoOfNodes;
private BTree()
{
Root = null;
NoOfNodes = 0;
}
//operaciones
public boolean IsEmpty() //busca valor en NoOfNodes
{
return(NoOfNodes == 0);
}
public BinaryNode gRoot()
{
return Root;
}
public int Count() //valor de NoOfNodes
{
return NoOfNodes;
}
//size del arbol
public int Size(BinaryNode ATree)
{
if (ATree == null)
return 0;
else
return(1 + Size(ATree.gLeft()) + Size(ATree.gRight()));
}
//niveles
public int Height(BinaryNode ATree)
{
if (ATree == null)
return 0;
else
return (1 + Math.max(Height(ATree.gLeft()), Height(ATree.gRight())));
}
//traversales
public void PreOrder(BinaryNode ATree)
{
if (ATree != null)
{
System.out.println(ATree.gData());
PreOrder(ATree.gLeft());
PreOrder(ATree.gRight());
}
}
public void InOrder(BinaryNode ATree)
{
if (ATree != null)
{
InOrder(ATree.gLeft());
System.out.println(ATree.gData());
InOrder(ATree.gRight());
}
}
public void PostOrder(BinaryNode ATree)
{
if (ATree != null)
{
PostOrder(ATree.gLeft());
PostOrder(ATree.gRight());
System.out.println(ATree.gData());
}
}
//insertar valores
public void Insert(int AId, Object AValue)
{
BinaryNode Temp,Current,Parent;
if(Root == null)//tree is empty
{
Temp = new BinaryNode(AId,AValue);
Root = Temp;
NoOfNodes++;
}
else//tree is not empty
{
Temp = new BinaryNode(AId,AValue);
Current = Root;
while(true)//never ending while loop
{
Parent = Current;
if(AId < Current.gKey())
{//go left
Current = Current.gLeft();
if (Current == null)
{
Parent.sLeft(Temp);
NoOfNodes++;
return;//jump out of loop
}
}
else
{ //go right
Current = Current.gRight();
if(Current == null)
{
Parent.sRight(Temp);
NoOfNodes++;
return;
}
}
}
}
}
//search
public BinaryNode Find(int AKey)
{
BinaryNode Current = null;
if(!IsEmpty())
{
Current = Root; //start search at top of tree
while(Current.gKey() != AKey)
{
if(AKey < Current.gKey())
Current = Current.gLeft();
else
Current = Current.gRight();
if(Current == null)
return null;
}
}
return Current;
}
//succesor
public BinaryNode GetSuccessor(BinaryNode ANode)
{
BinaryNode Current,Successor,SuccessorParent;
Successor = ANode;
SuccessorParent = ANode;
Current = ANode.gRight();
while(Current !=null)
{
SuccessorParent = Successor;
Successor = Current;
Current = Current.gLeft();
}
if(Successor != ANode.gRight())
{
SuccessorParent.sLeft(Successor.gRight());
Successor.sRight(ANode.gRight());
}
return Successor;
}
public boolean Delete (int AKey)
{
BinaryNode Current, Parent;
boolean IsLeftChild = true;
Current = Root;
Parent = Root;
while (Current.gKey() != AKey)
{
Parent = Current;
if (AKey < Current.gKey())
{
IsLeftChild = true;
Current = Current.gLeft();
}
else
{
IsLeftChild = false;
Current = Current.gRight();
}
if(Current == null)
return false;
}
// if no children delete the node
if (Current.gLeft() == null && Current.gRight() == null)
{
if (Current == Root)
Root = Current.gLeft();
else
if (IsLeftChild)
Parent.sLeft(Current.gRight());
else
Parent.sRight(Current.gRight());
}
// if no right child replace with left subtree
else
{
if (Current.gRight() == null)
{
if (Current == Root)
Root = Current.gRight();
else
if (IsLeftChild)
Parent.sLeft(Current.gLeft());
else
Parent.sRight(Current.gLeft());
}
// if no left child replace with right subtree
else
{
if (Current.gLeft() == null)
{
if (Current == Root)
Root = Current.gLeft();
else
if (IsLeftChild)
Parent.sLeft(Current.gRight());
else
Parent.sRight(Current.gRight());
}
// two children so replace in order of successor
else
{
BinaryNode Successor = GetSuccessor(Current);
if (Current == Root)
Root = Successor;
else
if (IsLeftChild)
Parent.sLeft(Successor);
else
Parent.sRight(Successor);
Successor.sLeft(Current.gLeft());
}
}
}
NoOfNodes--;
return true;
}
public static void main(String[] args) {
BTree MyTree = new BTree();
BinaryNode NodeAt;
MyTree.Insert(12,"Jorge");
MyTree.Insert(4,"Andres");
MyTree.Insert(11,"Javier");
MyTree.Insert(1,"Jose");
MyTree.Insert(100,"Paty");
MyTree.Delete(1);
MyTree.InOrder(MyTree.gRoot());
NodeAt = MyTree.Find(11);
if(NodeAt !=null)
System.out.println("Data in Node with Key 11 = " + NodeAt.gData());
System.exit(0);
}
}
BinaryNode Class
package evidencia2datos;
public class BinaryNode {
private int Key;
private Object Data;
private BinaryNode Left;
private BinaryNode Right;
public BinaryNode()
{
java.util.Scanner scaniar = new java.util.Scanner(System.in);
System.out.print("Enter in Key Value: ");
Key = scaniar.nextInt();
System.out.print("Enter in data: ");
Data = scaniar.nextInt();
Left = null;
Right = null;
}
//get
public int gKey()
{
return Key;
}
public Object gData()
{
return Data;
}
public BinaryNode gLeft()
{
return Left;
}
public BinaryNode gRight()
{
return Right;
}
//set
public void sKey(int AValue)
{
Key = AValue;
}
public void sData(Object AValue)
{
Data = AValue;
}
public void sLeft( BinaryNode AValue)
{
Left = AValue;
}
public void sRight( BinaryNode AValue)
{
Right = AValue;
}
}
You can create a new BinaryNode constructor which takes two arguments
BinaryNode (){
...
}
//Este es el nuevo constructor, como se puede observar
//toma dos argumentos
BinaryNode (int k, Object d){
key = k;
data = d;
...
}
I hope this will help you.
Im writing code to delete a node in a binary tree.All cases work except the "delete root with 2 children" case.
Here's my code:
Main.java
public class Main {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
binaryTree.add(50);
binaryTree.add(40);
binaryTree.add(39);
binaryTree.add(42);
binaryTree.add(41);
binaryTree.add(43);
binaryTree.add(55);
binaryTree.add(65);
binaryTree.add(60);
binaryTree.inOrderTraversal(binaryTree.root);
System.out.println();
binaryTree.removeNode(50);
binaryTree.inOrderTraversal(binaryTree.root);
}
}
BinaryTree.java
public class BinaryTree {
Node root = null;
Node deleteNode = null;
boolean isLeftChild = false;
Node parent = root;
public void add(int d)
{
Node newNode = new Node(d);
if(root!=null)
{
Node futureParent = root;
while(true)
{
if(newNode.data < futureParent.data) //going left
{
if(futureParent.left == null)
{
futureParent.left = newNode;
newNode.parent = futureParent;
break;
}
futureParent = futureParent.left;
}
else
{
if(futureParent.right == null)
{
futureParent.right = newNode;
newNode.parent = futureParent;
break;
}
futureParent = futureParent.right;
}
}
}
else
{
root = newNode;
}
}
public void inOrderTraversal(Node node)
{
if(node!=null)
{
inOrderTraversal(node.left);
System.out.println(node.data);
inOrderTraversal(node.right);
}
}
public void findNode(int n)
{
}
public void removeNode(int n)
{
deleteNode = root;
while(deleteNode!=null)
{
if(n == deleteNode.data)
{
break;
}
parent = deleteNode;
if(n < deleteNode.data)
{
deleteNode = deleteNode.left;
if(deleteNode.data == n)
{
isLeftChild = true;
break;
}
}
else
{
deleteNode = deleteNode.right;
if(deleteNode.data == n)
{
isLeftChild = false;
break;
}
}
}
//Case 1: No children at all
if((deleteNode.left == null)&&(deleteNode.right == null))
{
parent.right = null;
//incomplete code
}
//Case 2:No right child
else if(deleteNode.right == null)
{
deleteNoRightChild();
}
//Case 3:No left child
else if(deleteNode.left == null)
{
deleteNoLeftChild();
}
//Case 4:Both Children
else
{
Node minRightNode = deleteNode.right;
while (minRightNode.left != null)
{
parent = minRightNode;
minRightNode = minRightNode.left;
}
// minRightNode.parent.left = null;
deleteNode.data = minRightNode.data;
deleteNode = minRightNode;
if(minRightNode.left == null)
{
deleteNoLeftChild();
}
else if(minRightNode.right == null)
{
deleteNoRightChild();
}
else if((minRightNode.right == null)&&(minRightNode.left == null))
{
minRightNode.parent.left = null;
}
}
}
private void deleteNoLeftChild() {
if(deleteNode == root)
{
root = deleteNode.right;
}
if(isLeftChild)
{
parent.left = deleteNode.right;
}
else
{
parent.right = deleteNode.right;
}
}
private void deleteNoRightChild() {
if(deleteNode == root)
{ //Case 2.1:deleteNode is root
root = deleteNode.left;
}
if(isLeftChild)
{
//Case 2.2: Case 2, and its a left child
parent.left = deleteNode.left;
}
else
{
//Case 2.3: Case 2, and its a right child
parent.right = deleteNode.left;
}
}
}
Node.java
public class Node {
int data;
Node left;
Node right;
Node parent;
public Node(int d)
{
data = d;
left = null;
right = null;
}
}
As you can see, I am trying to delete 50 in Main.java.I debugged my code and tracked down the location giving out the NullPointerException and its in the deleteNoLeftChild() routine that I wrote.Following is a screenshot:
Please open image in new tab.
The blue line highlighted in the code window is the point of exception which is strange as the right side of the assignment(deleteNode.right) is not null.
The problem lies within the lines
//Case 4:Both Children
else
{
Node minRightNode = deleteNode.right;
while (minRightNode.left != null)
{
parent = minRightNode;
minRightNode = minRightNode.left;
}
...
}
You are setting the parent only if the minimum right node has a left child. In your scenario this is not true, hence parent not set/ null. You can test this by changing the layout of the tree.
Working on an InOrderIterator traversal method. I understand how to do this recursively but I keep getting this complier error.
inOrderIterator() in LinkedBinarySearchTree<T> cannot be applied to (BinaryTreeNode<T>)
Im not sure why I can't apply this method to that object. Any ideas?
Heres my method so far
public ArrayList<T> inOrderIterator()
{
ArrayList<T> myArr = new ArrayList<T>();
BinaryTreeNode<T> currentNode = this.root;
if(currentNode != null)
{
inOrderIterator(currentNode.getLeftChild());
myArr.add(currentNode.getElement());
inOrderIterator(currentNode.getRightChild());
}
return myArr;
}
LinkedBinarySearchTree.java
import jss2.exceptions.EmptyCollectionException;
import jss2.exceptions.ElementNotFoundException;
import java.util.ArrayList;
public class LinkedBinarySearchTree<T extends Comparable<T>>
{
private T elem;
BinaryTreeNode<T> root;
public LinkedBinarySearchTree (T element)
{
elem = element;
root = null;
}
public LinkedBinarySearchTree ()
{
root = null;
}
public void addToTree (T element)
{
//Check if root is null
if(root == null)
{
root.getElement().equals(element);
}
else
{
addToTreeHelper(root, element);
}
}
public void addToTreeHelper(BinaryTreeNode<T> node, T target)
{
BinaryTreeNode<T> child;
BinaryTreeNode<T> targetNode = new BinaryTreeNode<T>(target);
if(target.compareTo(node.getElement()) == -1)
{
child = node.getLeftChild();
if(child == null)
{
node.setLeftChild(targetNode);
}
else
{
addToTreeHelper(node.getLeftChild(), target);
}
}
else if(target.compareTo(node.getElement()) >= 0)
{
child = node.getRightChild();
if(child == null)
{
node.setRightChild(targetNode);
}
else
{
addToTreeHelper(node.getRightChild(), target);
}
}
}
//remove Element
public void removeElement(T target) throws Exception
{
BinaryTreeNode<T> node;
if(root.getElement() == null)
{
throw new EmptyCollectionException("tree is empty");
}
else if(target.compareTo(root.getElement()) == 0)
{
root = getReplacement(root);
}
else
{
node = removeElemHelper(root, target);
if(node == null)
{
throw new ElementNotFoundException ("not found "+target.toString());
}
}
}
//remove element helper
public BinaryTreeNode<T> removeElemHelper(BinaryTreeNode<T> node, T target)
{
BinaryTreeNode<T> result, child, replacement;
result = null;
if(node != null)
{
if(target.compareTo(node.getElement()) == -1)
{
child = node.getLeftChild();
if(child != null && target.compareTo(child.getElement()) == 0)
{
result = child;
replacement = getReplacement(child);
if(replacement == null)
{
node.setLeftChild(null);
}
else
{
node.setLeftChild(replacement);
}
}
else
{
result = removeElemHelper(child, target);
}
}
//
else if(target.compareTo(node.getElement()) == 1)
{
child = node.getRightChild();
if(child != null && target.compareTo(child.getElement()) == 0)
{
result = child;
replacement = getReplacement(child);
if(replacement == null)
{
node.setRightChild(null);
}
else
{
node.setRightChild(replacement);
}
}
else
{
result = removeElemHelper(child, target);
}
}
}
return result;
}
//replacement
public BinaryTreeNode<T> getReplacement(BinaryTreeNode<T> node)
{
BinaryTreeNode<T> result,leftChild, rightChild;
leftChild = node.getLeftChild();
rightChild = node.getRightChild();
if(node.getLeftChild() == null && node.getRightChild() == null)
{
result = null;
}
else if(node.getLeftChild() == null && node.getRightChild() != null)
{
result = node.getRightChild();
}
else if(node.getLeftChild() != null && node.getRightChild() == null)
{
result = node.getLeftChild();
}
else
{
result = findInorderSucessor(rightChild);
result.setLeftChild(leftChild);
result.setRightChild(rightChild);
}
return result;
}
//findInorderSucessor
private BinaryTreeNode<T> findInorderSucessor(BinaryTreeNode<T> node)
{
BinaryTreeNode<T> child = node.getLeftChild();
if(child == node)
{
return node;
}
else if(child.getLeftChild() == null)
{
child.setRightChild(node.getLeftChild());
}
return findInorderSucessor(child);
}
public ArrayList<T> inOrderIterator()
{
ArrayList<T> myArr = new ArrayList<T>();
BinaryTreeNode<T> currentNode = this.root;
if(currentNode != null)
{
inOrderIterator(currentNode.getLeftChild());
myArr.add(currentNode.getElement());
inOrderIterator(currentNode.getRightChild());
}
return myArr;
}
}
Look at your method declaration:
public ArrayList<T> inOrderIterator()
It doesn't have any parameters. But look how you're trying to invoke it:
inOrderIterator(currentNode.getRightChild());
... you're specifying an argument. There's no method which is applicable for that call.
I suspect you want to overload the method to have a private method accepting a node and a List<T> (the one you're building up), and then make your public method call that. For example:
public List<T> inOrderIterator() {
List<T> list = new ArrayList<T>();
inOrderIterator(list, this.root);
return list;
}
private void inOrderIterator(List<T> list, BinaryTreeNode<T> current) {
if (current == null) {
return;
}
inOrderIterator(current.getLeftChild());
list.add(current);
inOrderIterator(current.getRightChild());
}
I'm writing a program that utilizes a binary search tree to store data. In a previous program (unrelated), I was able to implement a linked list using an implementation provided with Java SE6. Is there something similar for a binary search tree, or will I need to "start from scratch"?
You can use a TreeMap data structure. TreeMap is implemented as a red black tree, which is a self-balancing binary search tree.
According to Collections Framework Overview you have two balanced tree implementations:
TreeSet
TreeMap
Here is my simple binary search tree implementation in Java SE 1.8:
public class BSTNode
{
int data;
BSTNode parent;
BSTNode left;
BSTNode right;
public BSTNode(int data)
{
this.data = data;
this.left = null;
this.right = null;
this.parent = null;
}
public BSTNode()
{
}
}
public class BSTFunctions
{
BSTNode ROOT;
public BSTFunctions()
{
this.ROOT = null;
}
void insertNode(BSTNode node, int data)
{
if (node == null)
{
node = new BSTNode(data);
ROOT = node;
}
else if (data < node.data && node.left == null)
{
node.left = new BSTNode(data);
node.left.parent = node;
}
else if (data >= node.data && node.right == null)
{
node.right = new BSTNode(data);
node.right.parent = node;
}
else
{
if (data < node.data)
{
insertNode(node.left, data);
}
else
{
insertNode(node.right, data);
}
}
}
public boolean search(BSTNode node, int data)
{
if (node == null)
{
return false;
}
else if (node.data == data)
{
return true;
}
else
{
if (data < node.data)
{
return search(node.left, data);
}
else
{
return search(node.right, data);
}
}
}
public void printInOrder(BSTNode node)
{
if (node != null)
{
printInOrder(node.left);
System.out.print(node.data + " - ");
printInOrder(node.right);
}
}
public void printPostOrder(BSTNode node)
{
if (node != null)
{
printPostOrder(node.left);
printPostOrder(node.right);
System.out.print(node.data + " - ");
}
}
public void printPreOrder(BSTNode node)
{
if (node != null)
{
System.out.print(node.data + " - ");
printPreOrder(node.left);
printPreOrder(node.right);
}
}
public static void main(String[] args)
{
BSTFunctions f = new BSTFunctions();
/**
* Insert
*/
f.insertNode(f.ROOT, 20);
f.insertNode(f.ROOT, 5);
f.insertNode(f.ROOT, 25);
f.insertNode(f.ROOT, 3);
f.insertNode(f.ROOT, 7);
f.insertNode(f.ROOT, 27);
f.insertNode(f.ROOT, 24);
/**
* Print
*/
f.printInOrder(f.ROOT);
System.out.println("");
f.printPostOrder(f.ROOT);
System.out.println("");
f.printPreOrder(f.ROOT);
System.out.println("");
/**
* Search
*/
System.out.println(f.search(f.ROOT, 27) ? "Found" : "Not Found");
System.out.println(f.search(f.ROOT, 10) ? "Found" : "Not Found");
}
}
And the output is:
3 - 5 - 7 - 20 - 24 - 25 - 27 -
3 - 7 - 5 - 24 - 27 - 25 - 20 -
20 - 5 - 3 - 7 - 25 - 24 - 27 -
Found
Not Found
Here is a sample implementation:
import java.util.*;
public class MyBSTree<K,V> implements MyTree<K,V>{
private BSTNode<K,V> _root;
private int _size;
private Comparator<K> _comparator;
private int mod = 0;
public MyBSTree(Comparator<K> comparator){
_comparator = comparator;
}
public Node<K,V> root(){
return _root;
}
public int size(){
return _size;
}
public boolean containsKey(K key){
if(_root == null){
return false;
}
BSTNode<K,V> node = _root;
while (node != null){
int comparison = compare(key, node.key());
if(comparison == 0){
return true;
}else if(comparison <= 0){
node = node._left;
}else {
node = node._right;
}
}
return false;
}
private int compare(K k1, K k2){
if(_comparator != null){
return _comparator.compare(k1,k2);
}
else {
Comparable<K> comparable = (Comparable<K>)k1;
return comparable.compareTo(k2);
}
}
public V get(K key){
Node<K,V> node = node(key);
return node != null ? node.value() : null;
}
private BSTNode<K,V> node(K key){
if(_root != null){
BSTNode<K,V> node = _root;
while (node != null){
int comparison = compare(key, node.key());
if(comparison == 0){
return node;
}else if(comparison <= 0){
node = node._left;
}else {
node = node._right;
}
}
}
return null;
}
public void add(K key, V value){
if(key == null){
throw new IllegalArgumentException("key");
}
if(_root == null){
_root = new BSTNode<K, V>(key, value);
}
BSTNode<K,V> prev = null, curr = _root;
boolean lastChildLeft = false;
while(curr != null){
int comparison = compare(key, curr.key());
prev = curr;
if(comparison == 0){
curr._value = value;
return;
}else if(comparison < 0){
curr = curr._left;
lastChildLeft = true;
}
else{
curr = curr._right;
lastChildLeft = false;
}
}
mod++;
if(lastChildLeft){
prev._left = new BSTNode<K, V>(key, value);
}else {
prev._right = new BSTNode<K, V>(key, value);
}
}
private void removeNode(BSTNode<K,V> curr){
if(curr.left() == null && curr.right() == null){
if(curr == _root){
_root = null;
}else{
if(curr.isLeft()) curr._parent._left = null;
else curr._parent._right = null;
}
}
else if(curr._left == null && curr._right != null){
curr._key = curr._right._key;
curr._value = curr._right._value;
curr._left = curr._right._left;
curr._right = curr._right._right;
}
else if(curr._left != null && curr._right == null){
curr._key = curr._left._key;
curr._value = curr._left._value;
curr._right = curr._left._right;
curr._left = curr._left._left;
}
else { // both left & right exist
BSTNode<K,V> x = curr._left;
// find right-most node of left sub-tree
while (x._right != null){
x = x._right;
}
// move that to current
curr._key = x._key;
curr._value = x._value;
// delete duplicate data
removeNode(x);
}
}
public V remove(K key){
BSTNode<K,V> curr = _root;
V val = null;
while(curr != null){
int comparison = compare(key, curr.key());
if(comparison == 0){
val = curr._value;
removeNode(curr);
mod++;
break;
}else if(comparison < 0){
curr = curr._left;
}
else{
curr = curr._right;
}
}
return val;
}
public Iterator<MyTree.Node<K,V>> iterator(){
return new MyIterator();
}
private class MyIterator implements Iterator<Node<K,V>>{
int _startMod;
Stack<BSTNode<K,V>> _stack;
public MyIterator(){
_startMod = MyBSTree.this.mod;
_stack = new Stack<BSTNode<K, V>>();
BSTNode<K,V> node = MyBSTree.this._root;
while (node != null){
_stack.push(node);
node = node._left;
}
}
public void remove(){
throw new UnsupportedOperationException();
}
public boolean hasNext(){
if(MyBSTree.this.mod != _startMod){
throw new ConcurrentModificationException();
}
return !_stack.empty();
}
public Node<K,V> next(){
if(MyBSTree.this.mod != _startMod){
throw new ConcurrentModificationException();
}
if(!hasNext()){
throw new NoSuchElementException();
}
BSTNode<K,V> node = _stack.pop();
BSTNode<K,V> x = node._right;
while (x != null){
_stack.push(x);
x = x._left;
}
return node;
}
}
#Override
public String toString(){
if(_root == null) return "[]";
return _root.toString();
}
private static class BSTNode<K,V> implements Node<K,V>{
K _key;
V _value;
BSTNode<K,V> _left, _right, _parent;
public BSTNode(K key, V value){
if(key == null){
throw new IllegalArgumentException("key");
}
_key = key;
_value = value;
}
public K key(){
return _key;
}
public V value(){
return _value;
}
public Node<K,V> left(){
return _left;
}
public Node<K,V> right(){
return _right;
}
public Node<K,V> parent(){
return _parent;
}
boolean isLeft(){
if(_parent == null) return false;
return _parent._left == this;
}
boolean isRight(){
if(_parent == null) return false;
return _parent._right == this;
}
#Override
public boolean equals(Object o){
if(o == null){
return false;
}
try{
BSTNode<K,V> node = (BSTNode<K,V>)o;
return node._key.equals(_key) && ((_value == null && node._value == null) || (_value != null && _value.equals(node._value)));
}catch (ClassCastException ex){
return false;
}
}
#Override
public int hashCode(){
int hashCode = _key.hashCode();
if(_value != null){
hashCode ^= _value.hashCode();
}
return hashCode;
}
#Override
public String toString(){
String leftStr = _left != null ? _left.toString() : "";
String rightStr = _right != null ? _right.toString() : "";
return "["+leftStr+" "+_key+" "+rightStr+"]";
}
}
}
This program has a functions for
Add Node
Display BST(Inorder)
Find Element
Find Successor
class BNode{
int data;
BNode left, right;
public BNode(int data){
this.data = data;
this.left = null;
this.right = null;
}
}
public class BST {
static BNode root;
public int add(int value){
BNode newNode, current;
newNode = new BNode(value);
if(root == null){
root = newNode;
current = root;
}
else{
current = root;
while(current.left != null || current.right != null){
if(newNode.data < current.data){
if(current.left != null)
current = current.left;
else
break;
}
else{
if(current.right != null)
current = current.right;
else
break;
}
}
if(newNode.data < current.data)
current.left = newNode;
else
current.right = newNode;
}
return value;
}
public void inorder(BNode root){
if (root != null) {
inorder(root.left);
System.out.println(root.data);
inorder(root.right);
}
}
public boolean find(int value){
boolean flag = false;
BNode current;
current = root;
while(current!= null){
if(current.data == value){
flag = true;
break;
}
else if(current.data > value)
current = current.left;
else
current = current.right;
}
System.out.println("Is "+value+" present in tree? : "+flag);
return flag;
}
public void successor(int value){
BNode current;
current = root;
if(find(value)){
while(current.data != value){
if(value < current.data && current.left != null){
System.out.println("Node is: "+current.data);
current = current.left;
}
else if(value > current.data && current.right != null){
System.out.println("Node is: "+current.data);
current = current.right;
}
}
}
else
System.out.println(value+" Element is not present in tree");
}
public static void main(String[] args) {
BST b = new BST();
b.add(50);
b.add(30);
b.add(20);
b.add(40);
b.add(70);
b.add(60);
b.add(80);
b.add(90);
b.inorder(root);
b.find(30);
b.find(90);
b.find(100);
b.find(50);
b.successor(90);
System.out.println();
b.successor(70);
}
}
Here is the complete Implementation of Binary Search Tree In Java insert,search,countNodes,traversal,delete,empty,maximum & minimum node,find parent node,print all leaf node, get level,get height, get depth,print left view, mirror view
import java.util.NoSuchElementException;
import java.util.Scanner;
import org.junit.experimental.max.MaxCore;
class BSTNode {
BSTNode left = null;
BSTNode rigth = null;
int data = 0;
public BSTNode() {
super();
}
public BSTNode(int data) {
this.left = null;
this.rigth = null;
this.data = data;
}
#Override
public String toString() {
return "BSTNode [left=" + left + ", rigth=" + rigth + ", data=" + data + "]";
}
}
class BinarySearchTree {
BSTNode root = null;
public BinarySearchTree() {
}
public void insert(int data) {
BSTNode node = new BSTNode(data);
if (root == null) {
root = node;
return;
}
BSTNode currentNode = root;
BSTNode parentNode = null;
while (true) {
parentNode = currentNode;
if (currentNode.data == data)
throw new IllegalArgumentException("Duplicates nodes note allowed in Binary Search Tree");
if (currentNode.data > data) {
currentNode = currentNode.left;
if (currentNode == null) {
parentNode.left = node;
return;
}
} else {
currentNode = currentNode.rigth;
if (currentNode == null) {
parentNode.rigth = node;
return;
}
}
}
}
public int countNodes() {
return countNodes(root);
}
private int countNodes(BSTNode node) {
if (node == null) {
return 0;
} else {
int count = 1;
count += countNodes(node.left);
count += countNodes(node.rigth);
return count;
}
}
public boolean searchNode(int data) {
if (empty())
return empty();
return searchNode(data, root);
}
public boolean searchNode(int data, BSTNode node) {
if (node != null) {
if (node.data == data)
return true;
else if (node.data > data)
return searchNode(data, node.left);
else if (node.data < data)
return searchNode(data, node.rigth);
}
return false;
}
public boolean delete(int data) {
if (empty())
throw new NoSuchElementException("Tree is Empty");
BSTNode currentNode = root;
BSTNode parentNode = root;
boolean isLeftChild = false;
while (currentNode.data != data) {
parentNode = currentNode;
if (currentNode.data > data) {
isLeftChild = true;
currentNode = currentNode.left;
} else if (currentNode.data < data) {
isLeftChild = false;
currentNode = currentNode.rigth;
}
if (currentNode == null)
return false;
}
// CASE 1: node with no child
if (currentNode.left == null && currentNode.rigth == null) {
if (currentNode == root)
root = null;
if (isLeftChild)
parentNode.left = null;
else
parentNode.rigth = null;
}
// CASE 2: if node with only one child
else if (currentNode.left != null && currentNode.rigth == null) {
if (root == currentNode) {
root = currentNode.left;
}
if (isLeftChild)
parentNode.left = currentNode.left;
else
parentNode.rigth = currentNode.left;
} else if (currentNode.rigth != null && currentNode.left == null) {
if (root == currentNode)
root = currentNode.rigth;
if (isLeftChild)
parentNode.left = currentNode.rigth;
else
parentNode.rigth = currentNode.rigth;
}
// CASE 3: node with two child
else if (currentNode.left != null && currentNode.rigth != null) {
// Now we have to find minimum element in rigth sub tree
// that is called successor
BSTNode successor = getSuccessor(currentNode);
if (currentNode == root)
root = successor;
if (isLeftChild)
parentNode.left = successor;
else
parentNode.rigth = successor;
successor.left = currentNode.left;
}
return true;
}
private BSTNode getSuccessor(BSTNode deleteNode) {
BSTNode successor = null;
BSTNode parentSuccessor = null;
BSTNode currentNode = deleteNode.left;
while (currentNode != null) {
parentSuccessor = successor;
successor = currentNode;
currentNode = currentNode.left;
}
if (successor != deleteNode.rigth) {
parentSuccessor.left = successor.left;
successor.rigth = deleteNode.rigth;
}
return successor;
}
public int nodeWithMinimumValue() {
return nodeWithMinimumValue(root);
}
private int nodeWithMinimumValue(BSTNode node) {
if (node.left != null)
return nodeWithMinimumValue(node.left);
return node.data;
}
public int nodewithMaximumValue() {
return nodewithMaximumValue(root);
}
private int nodewithMaximumValue(BSTNode node) {
if (node.rigth != null)
return nodewithMaximumValue(node.rigth);
return node.data;
}
public int parent(int data) {
return parent(root, data);
}
private int parent(BSTNode node, int data) {
if (empty())
throw new IllegalArgumentException("Empty");
if (root.data == data)
throw new IllegalArgumentException("No Parent node found");
BSTNode parent = null;
BSTNode current = node;
while (current.data != data) {
parent = current;
if (current.data > data)
current = current.left;
else
current = current.rigth;
if (current == null)
throw new IllegalArgumentException(data + " is not a node in tree");
}
return parent.data;
}
public int sibling(int data) {
return sibling(root, data);
}
private int sibling(BSTNode node, int data) {
if (empty())
throw new IllegalArgumentException("Empty");
if (root.data == data)
throw new IllegalArgumentException("No Parent node found");
BSTNode cureent = node;
BSTNode parent = null;
boolean isLeft = false;
while (cureent.data != data) {
parent = cureent;
if (cureent.data > data) {
cureent = cureent.left;
isLeft = true;
} else {
cureent = cureent.rigth;
isLeft = false;
}
if (cureent == null)
throw new IllegalArgumentException("No Parent node found");
}
if (isLeft) {
if (parent.rigth != null) {
return parent.rigth.data;
} else
throw new IllegalArgumentException("No Sibling is there");
} else {
if (parent.left != null)
return parent.left.data;
else
throw new IllegalArgumentException("No Sibling is there");
}
}
public void leafNodes() {
if (empty())
throw new IllegalArgumentException("Empty");
leafNode(root);
}
private void leafNode(BSTNode node) {
if (node == null)
return;
if (node.rigth == null && node.left == null)
System.out.print(node.data + " ");
leafNode(node.left);
leafNode(node.rigth);
}
public int level(int data) {
if (empty())
throw new IllegalArgumentException("Empty");
return level(root, data, 1);
}
private int level(BSTNode node, int data, int level) {
if (node == null)
return 0;
if (node.data == data)
return level;
int result = level(node.left, data, level + 1);
if (result != 0)
return result;
result = level(node.rigth, data, level + 1);
return result;
}
public int depth() {
return depth(root);
}
private int depth(BSTNode node) {
if (node == null)
return 0;
else
return 1 + Math.max(depth(node.left), depth(node.rigth));
}
public int height() {
return height(root);
}
private int height(BSTNode node) {
if (node == null)
return 0;
else
return 1 + Math.max(height(node.left), height(node.rigth));
}
public void leftView() {
leftView(root);
}
private void leftView(BSTNode node) {
if (node == null)
return;
int height = height(node);
for (int i = 1; i <= height; i++) {
printLeftView(node, i);
}
}
private boolean printLeftView(BSTNode node, int level) {
if (node == null)
return false;
if (level == 1) {
System.out.print(node.data + " ");
return true;
} else {
boolean left = printLeftView(node.left, level - 1);
if (left)
return true;
else
return printLeftView(node.rigth, level - 1);
}
}
public void mirroeView() {
BSTNode node = mirroeView(root);
preorder(node);
System.out.println();
inorder(node);
System.out.println();
postorder(node);
System.out.println();
}
private BSTNode mirroeView(BSTNode node) {
if (node == null || (node.left == null && node.rigth == null))
return node;
BSTNode temp = node.left;
node.left = node.rigth;
node.rigth = temp;
mirroeView(node.left);
mirroeView(node.rigth);
return node;
}
public void preorder() {
preorder(root);
}
private void preorder(BSTNode node) {
if (node != null) {
System.out.print(node.data + " ");
preorder(node.left);
preorder(node.rigth);
}
}
public void inorder() {
inorder(root);
}
private void inorder(BSTNode node) {
if (node != null) {
inorder(node.left);
System.out.print(node.data + " ");
inorder(node.rigth);
}
}
public void postorder() {
postorder(root);
}
private void postorder(BSTNode node) {
if (node != null) {
postorder(node.left);
postorder(node.rigth);
System.out.print(node.data + " ");
}
}
public boolean empty() {
return root == null;
}
}
public class BinarySearchTreeTest {
public static void main(String[] l) {
System.out.println("Weleome to Binary Search Tree");
Scanner scanner = new Scanner(System.in);
boolean yes = true;
BinarySearchTree tree = new BinarySearchTree();
do {
System.out.println("\n1. Insert");
System.out.println("2. Search Node");
System.out.println("3. Count Node");
System.out.println("4. Empty Status");
System.out.println("5. Delete Node");
System.out.println("6. Node with Minimum Value");
System.out.println("7. Node with Maximum Value");
System.out.println("8. Find Parent node");
System.out.println("9. Count no of links");
System.out.println("10. Get the sibling of any node");
System.out.println("11. Print all the leaf node");
System.out.println("12. Get the level of node");
System.out.println("13. Depth of the tree");
System.out.println("14. Height of Binary Tree");
System.out.println("15. Left View");
System.out.println("16. Mirror Image of Binary Tree");
System.out.println("Enter Your Choice :: ");
int choice = scanner.nextInt();
switch (choice) {
case 1:
try {
System.out.println("Enter Value");
tree.insert(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 2:
System.out.println("Enter the node");
System.out.println(tree.searchNode(scanner.nextInt()));
break;
case 3:
System.out.println(tree.countNodes());
break;
case 4:
System.out.println(tree.empty());
break;
case 5:
try {
System.out.println("Enter the node");
System.out.println(tree.delete(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
case 6:
try {
System.out.println(tree.nodeWithMinimumValue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 7:
try {
System.out.println(tree.nodewithMaximumValue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 8:
try {
System.out.println("Enter the node");
System.out.println(tree.parent(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 9:
try {
System.out.println(tree.countNodes() - 1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 10:
try {
System.out.println("Enter the node");
System.out.println(tree.sibling(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 11:
try {
tree.leafNodes();
} catch (Exception e) {
System.out.println(e.getMessage());
}
case 12:
try {
System.out.println("Enter the node");
System.out.println("Level is : " + tree.level(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 13:
try {
System.out.println(tree.depth());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 14:
try {
System.out.println(tree.height());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 15:
try {
tree.leftView();
System.out.println();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 16:
try {
tree.mirroeView();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
default:
break;
}
tree.preorder();
System.out.println();
tree.inorder();
System.out.println();
tree.postorder();
} while (yes);
scanner.close();
}
}