import java.util.Scanner;
class SBBSTNode {
SBBSTNode left, right;
int data;
int height;
public SBBSTNode() {
left = null;
right = null;
data = 0;
height = 0;
}
public SBBSTNode(int n) {
left = null;
right = null;
data = n;
height = 0;
}}
class SelfBalancingBST {
private SBBSTNode root;
public SelfBalancingBST() {
root = null;
}
public boolean isEmpty() {
return root == null;
}
root = null;
}
public void insert(int data) {
root = insert(data, root);
}
private int height(SBBSTNode t ) {
return t == null ? -1 : t.height;
}
private int max(int lhs, int rhs) {
return lhs > rhs ? lhs : rhs;
}
private SBBSTNode insert(int x, SBBSTNode t) {
if (t == null)
t = new SBBSTNode(x);
else if (x < t.data) {
t.left = insert( x, t.left );
if (height( t.left ) - height( t.right ) == 2)
if (x < t.left.data)
t = rotateWithLeftChild( t );
else
t = doubleWithLeftChild( t );
}
else if (x > t.data) {
t.right = insert( x, t.right );
if (height( t.right ) - height( t.left ) == 2)
if (x > t.right.data)
t = rotateWithRightChild( t );
else
t = doubleWithRightChild( t );
}
else
; // duplicate; do nothing
t.height = max( height( t.left ), height( t.right ) ) + 1;
return t;
}
private SBBSTNode rotateWithLeftChild(SBBSTNode k2) {
SBBSTNode k1 = k2.left;
k2.left = k1.right;
k1.right = k2;
k2.height = max( height( k2.left ), height( k2.right ) ) + 1;
k1.height = max( height( k1.left ), k2.height ) + 1;
return k1;
}
private SBBSTNode rotateWithRightChild(SBBSTNode k1) {
SBBSTNode k2 = k1.right;
k1.right = k2.left;
k2.left = k1;
k1.height = max( height( k1.left ), height( k1.right ) ) + 1;
k2.height = max( height( k2.right ), k1.height ) + 1;
return k2;
}
private SBBSTNode doubleWithLeftChild(SBBSTNode k3) {
k3.left = rotateWithRightChild( k3.left );
return rotateWithLeftChild( k3 );
}
private SBBSTNode doubleWithRightChild(SBBSTNode k1) {
k1.right = rotateWithLeftChild( k1.right );
return rotateWithRightChild( k1 );
}
public int countNodes() {
return countNodes(root);
}
private int countNodes(SBBSTNode r) {
if (r == null)
return 0;
else {
int l = 1;
l += countNodes(r.left);
l += countNodes(r.right);
return l;
}}
public boolean search(int val) {
return search(root, val);
}
private boolean search(SBBSTNode r, int val) {
boolean found = false;
while ((r != null) && !found) {
int rval = r.data;
if (val < rval)
r = r.left;
else if (val > rval)
r = r.right;
else {
found = true;
break;
}
found = search(r, val);
}
return found;
}
public void inorder() {
inorder(root);
}
private void inorder(SBBSTNode r) {
if (r != null) {
inorder(r.left);
System.out.print(r.data +" ");
inorder(r.right);
}}
public void preorder() {
preorder(root);
}
private void preorder(SBBSTNode r) {
if (r != null) {
System.out.print(r.data +" ");
preorder(r.left);
preorder(r.right);
}}
public void postorder() {
postorder(root);
}
private void postorder(SBBSTNode r) {
if (r != null) {
postorder(r.left);
postorder(r.right);
System.out.print(r.data +" ");
}}}
public class BSTTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
SelfBalancingBST sbbst = new SelfBalancingBST();
char ch;
do {
System.out.println("\nSelf Balancing Binary Search Tree Operations: \n");
System.out.println("1. Insert ");
System.out.println("2. Search");
System.out.println("3. Count Nodes");
System.out.println("4. Check Empty");
System.out.println("5. Clear Tree");
System.out.print("Enter Your Choice: ");
int choice = scan.nextInt();
switch (choice) {
case 1 :
System.out.print("Enter An Integer To Insert: ");
sbbst.insert( scan.nextInt() );
break;
case 2 :
System.out.print("Enter An Integer To Search: ");
System.out.println("Search Result : "+ sbbst.search( scan.nextInt() ));
break;
case 3 :
System.out.println("Nodes = "+ sbbst.countNodes());
break;
case 4 :
System.out.println("Empty Status = "+ sbbst.isEmpty());
break;
case 5 :
System.out.println("\nTree Cleared");
sbbst.clear();
break;
default :
System.out.println("Wrong Entry ");
break;
}
System.out.print("\nPost Order : ");
sbbst.postorder();
System.out.print("\nPre Order : ");
sbbst.preorder();
System.out.print("\nIn Order : ");
sbbst.inorder();
System.out.println("\n\nDo You Want To Continue (Type Y OR N): ");
ch = scan.next().charAt(0);
} while (ch == 'Y'|| ch == 'y');
scan.close();
}}