I've written a boolean insert method that inserts values into a binary search tree which inserts the value if the value is not already there and returns true if so, and returns false if the value is already there so inserts nothing. I am trying to convert this iterative method into all recursion with no loops at all but I am having trouble with figuring out how. Any help is appreciated!
public boolean insert(int value) {
Node travel= root, prev= null, newNode;
boolean result= true;
while (travel != null && travel.data != value) {
prev= travel;
if (value < travel.data)
travel= travel.left;
else travel= travel.right;
}
if (travel != null)
result= false;
else
if (root == null)
root= new Node(value);
else
if (value < prev.data)
prev.left= new Node(value);
else prev.right= new Node(value);
return result;
}
http://www.java2s.com/Code/Java/Collections-Data-Structure/BinaryTree.htm
public class BinarySearchTree {
private Node root;
public boolean insert(int value) {
if (root == null) {
root = new Node(value);
return true;
} else {
return insert(root, value);
}
}
private boolean insert(Node node, int value) {
if (value < node.value) {
if (node.left != null) {
return insert(node.left, value);
} else {
node.left = new Node(value);
return true;
}
} else if (value > node.value) {
if (node.right != null) {
return insert(node.right, value);
} else {
node.right = new Node(value);
return true;
}
} else {
return false;
}
}
public void printInOrder(Node node) {
if (node != null) {
printInOrder(node.left);
System.out.println("Traversed " + node.value);
printInOrder(node.right);
}
}
public static void main(String[] args) {
BinarySearchTree t = new BinarySearchTree();
System.out.println("insert 5: " + t.insert(5));
System.out.println("insert 4: " + t.insert(4));
System.out.println("insert 7: " + t.insert(7));
System.out.println("insert 4: " + t.insert(4));
t.printInOrder(t.root);
}
}
class Node {
Node left;
Node right;
int value;
public Node(int value) {
this.value = value;
}
}
You may try the following:
public boolean insert(int value) {
return insert(value, root);
}
public boolean insert(int value, Node explore) {
if (explore != null) {
if (value < explore.data) {
if (explore.left != null) {
return insert(value, explore.left);
} else {
explore.left = new Node(value);
return true;
}
} else if (value > explore.data) {
if (explore.right != null) {
return insert(value, explore.right);
} else {
explore.right = new Node(value);
return true;
}
} else {
// In this case the value already exists
return false;
}
} else {
explore = new Node(value);
}
return true;
}
Related
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!
I have been trying to figure out why my countingLeaves method cannot be found when I call it from my tester class.
My compiler gives me the error TreeTester.java:25: error: cannot find symbol
countLeaves();
^
symbol: method countLeaves()
location: class TreeTester
public class BinarySearchTree
{
private Node root;
public BinarySearchTree()
{
root = null;
}
public void add(Comparable obj)
{
Node newNode = new Node();
newNode.data = obj;
newNode.left = null;
newNode.right = null;
if (root == null) { root = newNode; }
else { root.addNode(newNode); }
}
public boolean find(Comparable obj)
{
Node current = root;
while (current != null)
{
int d = current.data.compareTo(obj);
if (d == 0) { return true; }
else if (d > 0) { current = current.left; }
else { current = current.right; }
}
return false;
}
public void remove(Comparable obj)
{
Node toBeRemoved = root;
Node parent = null;
boolean found = false;
while (!found && toBeRemoved != null)
{
int d = toBeRemoved.data.compareTo(obj);
if (d == 0) { found = true; }
else
{
parent = toBeRemoved;
if (d > 0) { toBeRemoved = toBeRemoved.left; }
else { toBeRemoved = toBeRemoved.right; }
}
}
if (!found) { return; }
if (toBeRemoved.left == null || toBeRemoved.right == null)
{
Node newChild;
if (toBeRemoved.left == null)
{
newChild = toBeRemoved.right;
}
else
{
newChild = toBeRemoved.left;
}
if (parent == null) // Found in root
{
root = newChild;
}
else if (parent.left == toBeRemoved)
{
parent.left = newChild;
}
else
{
parent.right = newChild;
}
return;
}
Node smallestParent = toBeRemoved;
Node smallest = toBeRemoved.right;
while (smallest.left != null)
{
smallestParent = smallest;
smallest = smallest.left;
}
toBeRemoved.data = smallest.data;
if (smallestParent == toBeRemoved)
{
smallestParent.right = smallest.right;
}
else
{
smallestParent.left = smallest.right;
}
}
public void print()
{
print(root);
System.out.println();
}
private static void print(Node parent)
{
if (parent == null) { return; }
print(parent.left);
System.out.print(parent.data + " ");
print(parent.right);
}
public int countLeaves(Node node)
{
if(node == null)
return 0;
else if(node.left == null && node.right == null)
{
return 1;
}
else
{
return countLeaves(node.left) + countLeaves(node.right);
}
}
class Node
{
public Comparable data;
public Node left;
public Node right;
public void addNode(Node newNode)
{
int comp = newNode.data.compareTo(data);
if (comp < 0)
{
if (left == null) { left = newNode; }
else { left.addNode(newNode); }
}
else if (comp > 0)
{
if (right == null) { right = newNode; }
else { right.addNode(newNode); }
}
}
}
}
The tester class used
public class TreeTester
{
public static void main(String[] args)
{
BinarySearchTree t = new BinarySearchTree();
t.add("D");
t.add("B");
t.add("A");
t.add("C");
t.add("F");
t.add("E");
t.add("I");
t.add("G");
t.add("H");
t.add("J");
t.remove("A"); // Removing leaf
t.remove("B"); // Removing element with one child
t.remove("F"); // Removing element with two children
t.remove("D"); // Removing root
t.print();
System.out.println("Expected: C E G H I J");
countLeaves(t);
}
}
The countLeaves needs a Node, not a BinarySearchTree.
You may add a method in BinarySearchTree as this:
Node getRoot(){return root;}
Amd use countLeaves(t.getRoot()).
The countLeaves needs a Node, not a BinarySearchTree.
I am a bit stuck trying to create a print the path to TreeNode method. Not quite sure where I went wrong but I think it might be in the 2nd else.
code:
public static ArrayList<Integer> printPath(TreeNode node, ArrayList<Integer> path, int value) {
if (node == null) {
return path;
} else {
if (node.data == value) {
path.add(value);
return path;
} else {
path.add(node.data);
printPath(node.left, path, value);
printPath(node.right, path, value);
}
}
return path;
}
Currently I am getting output as [20, 8, 4, 12, 22] When I should be only getting [20,8,12].
I added the Binary search tree in the picture, path is an empty ArrayList, and value is 12
Assuming you want only the shortest path from the root-Node to the given value, you must compare the value with the current node's data and then decide whether to go left or right (and not go both directions).
public static ArrayList<Integer> printPath(TreeNode node, ArrayList<Integer> path, int value) {
if (node == null)
return path;
path.add(node.data);
int cmp = Integer.compare(value, node.data);
if (cmp < 0) // value is smaller, so go left
printPath(node.left, path, value);
else if (cmp > 0) // value is larger, so go right
printPath(node.right, path, value);
else /* if (cmp == 0) */
return path; // value found
return path;
}
This should give [20, 8, 12] for the proposed tree when calling:
printPath(root, new ArrayList<Integer>(), 12);
public static ArrayList<Integer> printPath(TreeNode node, ArrayList<Integer> path, int value) {
if (node == null) {
return path;
}
path.add(node.data);
if (node.data < value) {
printPath(node.right, path, value);
} else if(node.data>value){
printPath(node.left, path, value);
}
return path;
}
A testable Solution with some sample data:
import java.util.ArrayList;
import java.util.List;
class TreeNode
{
int data;
TreeNode left;
TreeNode right;
public TreeNode(int x) { data = x; }
public TreeNode(TreeNode node)
{
this.data = node.data;
this.left = node.left;
this.right = node.right;
}
public void add(TreeNode node)
{
if(data > node.data)
{
if(left == null)
left = node;
else
left.add(node);
}
if(data < node.data)
if(right == null)
right = node;
else
right.add(node);
}
}
class Tree
{
TreeNode root;
public Tree(TreeNode node)
{
this.root = node;
}
public Tree()
{
this.root = null;
}
public void add(TreeNode node)
{
if(root == null)
{
root = node;
}
if(root.data > node.data){
if(root.left == null)
root.left = node;
else
root.left.add(node);
}
if(root.data < node.data)
{
if(root.right == null)
root.right = node;
else
root.right.add(node);
}
}
public void addInt(int value){
add(new TreeNode(value));
}
public void postorder(TreeNode n)
{
if (n != null)
{
postorder(n.left);
postorder(n.right);
System.out.print(n.data + " ");
}
}
public void inorder(TreeNode n)
{
if (n != null)
{
inorder(n.left);
System.out.print(n.data + " ");
inorder(n.right);
}
}
}
public class TreeTest
{
public static void main(String[] args)
{
Tree tree = new Tree();
tree.add(new TreeNode(3));
tree.add(new TreeNode(2));
tree.add(new TreeNode(5));
tree.add(new TreeNode(9));
tree.add(new TreeNode(4));
tree.add(new TreeNode(1));
tree.add(new TreeNode(10));
tree.addInt(11);
ArrayList<Integer> mylist = printPath(tree.root, new ArrayList<Integer>(),10);
System.out.println("the path is "+mylist);
tree.inorder(tree.root);
System.out.println("");
tree.postorder(tree.root);
}
public static ArrayList<Integer> printPath(TreeNode node, ArrayList<Integer> path, int value) {
if (node == null) {
return path;
}
if (node.data == value) {
path.add(value);
return path;
}
if(node.data > value){
path.add(node.data);
printPath(node.left, path, value);
}
if(node.data < value) {
path.add(node.data);
printPath(node.right,path, value);
}
return path;
}
}
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();
}
}
I am trying to do a an avl tree which updates itself everytime the tree is unbalanced. The rotations are working but i have a bug where if for example the tree node 7, leftChild 6 , leftchild of leftchild 5 becomes node 6, leftchild 5, rightchild 7, and after balancing I add a new node, the node is first compared with 7 and not with 6. How do I fix this problem?
This is the main class:
import java.io.*;
import javax.swing.*;
import java.util.*;
import java.lang.*;
public class NewMain implements Cloneable{
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
File file = new File ("AVLTree.txt");
ArrayList <TreeNode> array = new ArrayList ();
Scanner kb = new Scanner (System.in);
int num = 0;
TreeNode root = new TreeNode ();
do {
System.out.print(" AVL Tree \n\n\n\n");
System.out.println("1. Create a new binary tree");
System.out.println("2. Save Tree");
System.out.println("3. Load Tree");
System.out.println("4. Enter a new node in the tree");
System.out.println("5. Show current AVL tree");
System.out.println("6. Show inorder traversal");
System.out.println("7. Search");
System.out.println("8. Quit \n\n\n\n\n\n\n");
System.out.print("Enter a number: ");
num = kb.nextInt ();
if (num == 1){
if (array.isEmpty ())
{
System.out.print ("Enter the root value: ");
int value = kb.nextInt ();
root = new TreeNode();
root.setValue(value);
array.add(root);
}
else
{
array.clear();
System.out.print ("Enter the root value: ");
int value = kb.nextInt ();
root = new TreeNode();
root.setValue(value);
array.add(root);
}
}
if (num == 2)
{
FileOutputStream outFile = null;
ObjectOutputStream oos = null;
try
{
outFile = new FileOutputStream(file);
oos = new ObjectOutputStream(outFile);
for (TreeNode list : array)
{
oos.writeObject(list);
}
oos.close();
}
catch (Exception e)
{
System.out.print("Save Not Successful!");
}
}
if (num == 3)
{
if (file.exists())
{
FileInputStream inFile = null;
ObjectInputStream ios = null;
try
{
Object obj = null;
inFile = new FileInputStream(file);
ios = new ObjectInputStream(inFile);
while ((obj = ios.readObject()) != null) {
if (obj instanceof TreeNode)
{
array.add((TreeNode) obj);
}
}
ios.close();
}
catch(EOFException e)
{
}
catch (Exception e)
{
System.out.print("File was not found while loading");
}
}
}
if (num == 4)
{
System.out.print ("Enter a new child node: ");
int value = kb.nextInt ();
try
{
array.add(root.insert(value));
root.balance();
}
catch (Exception e)
{
System.out.print (e.getMessage());
}
}
if (num == 5){
System.out.print ("Pointer Number\t\tLeft\t\tNode\t\tRight\t\tLeft Height\t\tRight Height\n");
for (int i=0; i<array.size();i++)
{
System.out.print (i+"\t\t\t"+array.indexOf(array.get(i).getLeftChild())+"\t\t"+array.get(i).getValue()+"\t\t"+array.indexOf(array.get(i).getRightChild())+"\t\t"+array.get(i).getLeftHeight()+"\t\t\t"+array.get(i).getRightHeight()+"\n");
}
}
if (num == 6)
{
System.out.print("Inorder traversal: ");
System.out.println(root.InOrderTraversal());
System.out.print("Postorder traversal: ");
System.out.println(root.PostOrderTraversal());
System.out.print("Preorder traversal: ");
System.out.println(root.PreOrderTraversal());
}
if (num == 7)
{
System.out.print("Enter node to be searched: ");
int node = kb.nextInt ();
for (int i = 0; i<array.size();i++)
{
if (node == array.get(i).getValue())
{
System.out.print ("Node is in index "+i+"\n");
break;
}
if (i == array.size()-1 && node != array.get(i).getValue())
{
System.out.print ("Node not found in the tree!"+"\n");
break;
}
}
}
}while (num != 8);
}
}
This is from a normal java class:
import java.lang.StringBuilder;
import java.util.ArrayList;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class TreeNode implements Serializable, Cloneable
{
public Integer value;
public TreeNode leftChild;
public TreeNode rightChild;
public TreeNode()
{
this.value = null;
this.leftChild = null;
this.rightChild = null;
}
public TreeNode(int value)
{
this.value = value;
this.leftChild = null;
this.rightChild = null;
}
public int getValue()
{
return this.value;
}
public void setValue(int value)
{
this.value = value;
}
public TreeNode getLeftChild()
{
return this.leftChild;
}
public void setLeftChild(TreeNode leftChild)
{
this.leftChild = leftChild;
}
public TreeNode getRightChild()
{
return this.rightChild;
}
public void setRightChild(TreeNode rightChild)
{
this.rightChild = rightChild;
}
public int getLeftHeight()
{
if (this.leftChild == null)
{
return 0;
}
else
{
return this.getLeftChild().getHeight() + 1;
}
}
public int getRightHeight()
{
if (this.rightChild == null)
{
return 0;
}
else
{
return this.getRightChild().getHeight() + 1;
}
}
public TreeNode insert(int value) throws Exception
{
if(this.value == null && this.leftChild == null && this.rightChild == null)
{
this.value = value;
return this;
}
else
{
TreeNode node = new TreeNode (value);
if(value < this.value)
{
if(this.getLeftChild() == null)
{
this.setLeftChild (node);
return node;
}
else
{
return this.getLeftChild().insert(value);
}
}
else if(value > this.value)
{
if(this.getRightChild() == null)
{
this.setRightChild(node);
return node;
}
else
{
return this.getRightChild().insert(value);
}
}
else
{
return null;
}
}
}
public TreeNode balance() throws Exception
{
if (Math.abs(this.getLeftHeight() - this.getRightHeight())==2)
{
if (this.rightChild == null)
{
if(this.leftChild.leftChild != null)
{
return this.LLRotation ();
}
if(this.leftChild.rightChild != null)
{
return this.LRRotation ();
}
}
if (this.leftChild == null)
{
if (this.rightChild.rightChild != null)
{
return this.RRRotation ();
}
if (this.rightChild.leftChild != null)
{
return this.RLRotation ();
}
}
}
else
{
if (this.getLeftChild () != null)
{
return this.getLeftChild().balance();
}
if (this.getRightChild () != null)
{
return this.getRightChild().balance();
}
}
return this;
}
public int getHeight ()
{
if (this.leftChild == null && this.rightChild == null)
{
return 0;
}
else
{
int leftH = 0;
int rightH = 0;
if (this.leftChild != null)
{
leftH++;
leftH += this.getLeftChild().getHeight();
}
if (this.rightChild != null)
{
rightH++;
rightH += this.getRightChild().getHeight();
}
return Math.max(leftH,rightH);
}
}
public TreeNode LLRotation ()
{
TreeNode temp = this.leftChild;
this.leftChild = null;
temp.rightChild = this;
return temp;
}
public TreeNode RRRotation ()
{
TreeNode temp = this.rightChild;
this.rightChild = temp.leftChild;
try
{
temp.leftChild = (TreeNode)this.clone();
}
catch (CloneNotSupportedException ex)
{
}
this.value = temp.value;
this.rightChild = temp.rightChild;
this.leftChild = temp.leftChild;
return temp;
}
public TreeNode LRRotation ()
{
this.leftChild = this.leftChild.RRRotation();
return LLRotation();
}
public TreeNode RLRotation ()
{
this.rightChild = this.rightChild.RRRotation();
return RRRotation();
}
public String InOrderTraversal ()
{
StringBuilder sb = new StringBuilder ();
if (this.leftChild == null && this.rightChild == null)
{
sb.append(this.value).append(" ");
}
else
{
if(this.leftChild != null)
{
sb.append(this.getLeftChild().InOrderTraversal());
}
sb.append(this.value).append(" ");
if (this.rightChild != null)
{
sb.append(this.getRightChild().InOrderTraversal());
}
}
return sb.toString();
}
public String PostOrderTraversal ()
{
StringBuilder sb = new StringBuilder ();
if (this.leftChild == null && this.rightChild == null)
{
sb.append(this.value).append(" ");
}
else
{
if(this.leftChild != null)
{
sb.append(this.getLeftChild().PostOrderTraversal());
}
if (this.rightChild != null)
{
sb.append(this.getRightChild().PostOrderTraversal());
}
sb.append(this.value).append(" ");
}
return sb.toString();
}
public String PreOrderTraversal ()
{
StringBuilder sb = new StringBuilder ();
if (this.leftChild == null && this.rightChild == null)
{
sb.append(this.value).append(" ");
}
else
{
sb.append(this.value).append(" ");
if(this.leftChild != null)
{
sb.append(this.getLeftChild().PreOrderTraversal());
}
if (this.rightChild != null)
{
sb.append(this.getRightChild().PreOrderTraversal());
}
}
return sb.toString();
}
}
The code is a bit more complex it needs to be. I hope here to give you a simpler version, which with you yourself may correctly balance. As maybe you should better do pointer rotation / rebalancing inside the insertion. Don't feel obliged to give points; this is but a half answer.
Remark only: the field value may be an ìnt.
It is definitely easier for recursive algorithms, if the "this" object might be null. This can be achieved by wrapping the entire tree in one public class, which uses the TreeNode class internally.
public class Tree {
private static class TreeNode {
private int value;
private TreeNode left;
private TreeNode right;
private TreeNode(int value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
}
private static class AlreadyExistsException extends Exception {
private TreeNode node;
private AlreadyExistsException(TreeNode node) {
this.node = node;
}
public TreeNode getNode() {
return node;
}
}
private TreeNode root;
private int size;
public boolean insert(int value) {
try {
root = insertInto(root, value);
++size;
return true;
} catch (AlreadyExistsException e) {
// Fine.
return false;
}
}
private TreeNode insertInto(TreeNode node, int value) throws AlreadyExistsException {
if (node == null) {
return new TreeNode(value, null, null);
}
if (value < node.value) {
node.left = insertInto(node.left, value);
return node;
} else if (value > node.value) {
node.right = insertInto(node.right, value);
return node;
} else {
throw new AlreadyExistsException(node);
}
}
}
As you see the for balancing immediately during the insertion, there could be done an insertion with pointer rotation at < and > (3 pointers: left's right-most leaf or right's left-most leaf). Comming back from recursion one could have collected the parent of the left's right-most leaf, and perform a rotation. Or at any other point. There exist 3 variants!
Probably because root is still pointing at the old node. Are you sure you want to ignore the return value of balance() at the marked line?
if (num == 4) {
System.out.print ("Enter a new child node: ");
int value = kb.nextInt ();
try {
array.add(root.insert(value));
root.balance(); // look here
} catch (Exception e) {
System.out.print (e.getMessage());
}
}
BTW, an AVL tree as described in the literature does not recurse of the entirety of the tree to find the balance of a node.