Binary Search Tree
Tree
Binary Search Tree

Node
public class Node
{
	private int data;
	private Node left;
	private Node right;
	private Node parent;

	public Node()
	{
		data = 0;
		left = null;
		right = null;
		parent = null;
	}

	public Node(int e)
	{
		data = e;
		left = null;
		right = null;
		parent = null;
	}

	public int getData()
	{
		return data;
	}

	public Node getLeft()
	{
		return left;
	}

	public Node getRight()
	{
		return right;
	}

	public Node getParent()
	{
		return parent;
	}

	public void setData(int d)
	{
		data = d;
	}

	public void setLeft(Node l)
	{
		left = l;
	}

	public void setRight(Node r)
	{
		right = r;
	}

	public void setParent(Node p)
	{
		parent = p;
	}
}
			
BST
public class BST
{
	private Node root;

	/** Initialize a tree
	 */
	public BST()
	{
		root = null;
	}

	/** Return the root of the tree
	 * @return {@code Node}, root of tree
	 */
	// O(1)
	public Node getRoot()
	{
		return root;
	}

	/** Set a node for root
	 * @param Node, node
	 * @return none
	 */
	// O(1)
	public void setRoot(Node n)
	{
		root = n;
	}

	/** Check if the tree is an empty tree
	 * @return {@code bool}, tree if tree is empty; false otherwise
	 */
	// O(1)
	public boolean isEmpty()
	{
		return (root == null);
	}

	/** Get the size of the tree
	 * @return {@code int}, number of elements in tree
	 */
	// O(n)
	public int size()
	{
		return getSize(root);
	}

	public int getSize(Node n)
	{
		if(n == null) return 0;
		return 1+getSize(n.getLeft())+getSize(n.getRight());
	}

	/** Check if two trees are same
	 * @param BST a binary search tree
	 * @return {@code bool}, tree if two trees are same; false otherwise
	 */
	// O(n)
	public boolean equals(BST t)
	{
		if(size() != t.size()) return false;
		return nodeEquals(root, t.root);
	}

	public boolean nodeEquals(Node n1, Node n2)
	{
		if(n1 == null && n2 == null) return true;
		if(n1 == null && n2 != null) return false;
		if(n1 != null & n2 == null) return false;
		if(n1.getData() != n2.getData()) return false;
		return nodeEquals(n1.getLeft(), n2.getLeft()) && nodeEquals(n1.getRight(), n2.getRight());
	}

	/** Print elements in ascending ord
	 */
	// O(n)
	public void inorderWalk()
	{
		if(root != null) printLDR(root);
		System.out.println();
	}

	public void printLDR(Node n)
	{
		if(n == null) return;
		printLDR(n.getLeft());
		System.out.printf("%5d", n.getData());
		printLDR(n.getRight());
	}

	/** Print element in pre-order
	 */
	// O(n)
	public void preorderWalk()
	{
		if(root != null) printDLR(root);
		System.out.println();
	}

	public void printDLR(Node n)
	{
		if(n == null) return;
		System.out.printf("%5d", n.getData());
		printDLR(n.getLeft());
		printDLR(n.getRight());
	}

	/** Print elements in post-order
	 */
	// O(n)
	public void postorderWalk()
	{
		if(root != null) printLRD(root);
		System.out.println();
	}

	public void printLRD(Node n)
	{
		if(n == null) return;
		printLRD(n.getLeft());
		printLRD(n.getRight());
		System.out.printf("%5d", n.getData());
	}

	/** Insert an element into the tree with the algorithm in CLRS
	 * @param, int value of inserting element
	 */
	// O(lgn)
	public void insert(int e)
	{
		if(search(e)) return;

		Node parent = null;
		Node current = root;

		while(current != null)
		{
			parent = current;
			current = (e < current.getData())?parent.getLeft():parent.getRight();
		}

		Node temp = new Node(e);
		temp.setParent(parent);
		if(parent == null)
			root = temp;
		else
		{
			if (e < parent.getData())
				parent.setLeft(temp);
			else
				parent.setRight(temp);
		}
	}

	/** Replace a subtree with other subtree
	 * @param u target subtree
	 * @param v replace subtree
	 */
	// O(1)
	public void transplant(Node u, Node v)
	{
		if(u.getParent() == null)
			root = v;
		else if(u == u.getParent().getLeft())
			u.getParent().setLeft(v);
		else
			u.getParent().setRight(v);
		if(v != null)
			v.setParent(u.getParent());
	}

	/** Delete an element in tree
	 * @param int value of an element
	 */
	// O(lgn)
	public void delete(int e)
	{
		if(!search(e)) return;

		Node z = searchNode(root, e);

		//z has no child or only one child
		if(z.getLeft() == null)
			transplant(z, z.getRight());
		else if(z.getRight() == null)
			transplant(z, z.getLeft());
		//z has two children
		else
		{
			Node y = getMin(z.getRight());
			if(y.getParent() != z)//y is not z's child
			{
				transplant(y, y.getRight());
				y.setRight(z.getRight());
				y.getRight().setParent(y);
			}
			transplant(z, y);
			y.setLeft(z.getLeft());
			y.getLeft().setParent(y);
		}
	}

	/** Get the successor of an element in tree
	 * @param int value of the element
	 * @return {@code int}, value of successor
	 */
	// O(lgn)
	public int successor(int e)
	{
		Node n = getSuccessor(root, e);
		if (n == null) return -1;

		return n.getData();
	}

	public Node getSuccessor(Node n, int e)
	{
		if(!search(e))
			return null;
		Node target = searchNode(n, e);

		//if the right subtree of node is nonempty
		if(target.getRight() != null)
			return getMin(target.getRight());

		Node p = target.getParent();

		//if node is leave, the right subtree is empty
		while (p != null && target == p.getRight()) {
            		target = p;
            		p = p.getParent();
        	}
		return p;
	}

	/** Get the predecessor of an element in tree
	 * @param int value of the element
	 * @return {@code int}, value of predecessor
	 */
	// O(lgn)
	public int predecessor(int e)
	{
		Node n = getPredecessor(root, e);
		if (n == null) return -1;

		return n.getData();
	}

	public Node getPredecessor(Node n, int e)
	{
		if(!search(e))
			return null;
		Node target = searchNode(n, e);

		//if the left subtree of node is nonempty
		if(target.getLeft() != null)
			return getMax(target.getLeft());

		Node p = target.getParent();

		//if node is leave, the left subtree is empty
		while(p != null && target == p.getLeft()){
			target = p;
			p = p.getParent();
		}
		return p;
	}

	/** Get the height of the tree
	 */
	// O(lgn)
	public int height()
	{
		return getHeight(root);
	}

	public int getHeight(Node n)
	{
		if(n == null) return 0;
		if(n.getLeft() == null && n.getRight() == null)
			return 1;

		int l = getHeight(n.getLeft());
		int r = getHeight(n.getRight());

		return (l>r)?(1+l):(1+r);
	}

	/** Search an element in tree
	 * @param int, the value of an element
	 * @return {@code boolean}, true if the tree contains the element and false otherwise
	 */
	// O(lgn)
	public boolean search(int e)
	{
		return searchNode(root, e) != null;
	}

	public Node searchNode(Node n, int e)
	{
		if(n == null) return null;
		if(n.getData() == e) return n;
		if(e < n.getData())
			return searchNode(n.getLeft(), e);
		else
			return searchNode(n.getRight(), e);
	}

	/** Get the minimum element in tree
	 * @param none
	 * @return {@code int}, value of the minimum element in tree
	 */
	// O(lgn)
	public int min()
	{
		Node n = getMin(root);
		return n.getData();
	}

	public Node getMin(Node n)
	{
		if(n.getLeft() == null)
			return n;
		return getMin(n.getLeft());
	}

	/** Get the maximum element in tree
	 * @param none
	 * @return int, value of the maximum element in tree
	 */
	// O(lgn)
	public int max()
	{
		Node n = getMax(root);
		return n.getData();
	}

	public Node getMax(Node n)
	{
		if(n.getRight() == null)
			return n;
		return getMax(n.getRight());
	}
}
			
Successor
  • Node has right child
  • Node has no right child
  • Predecessor
  • Node has left child
  • Node has no left child
  • Transplant

    Delete
  • Node has only right child
  • Node has only left child
  • Node has two children
  • BSTTest
    public class BSTTest
    {
    	public static void main(String args[])
    	{
    		BST t = new BST();
    
    		// Create tree
    		t.insert(8);
    		t.insert(3);
    		t.insert(10);
    		t.insert(1);
    		t.insert(6);
    		t.insert(14);
    		t.insert(4);
    		t.insert(7);
    		t.insert(13);
    		t.insert(15);
    
    		// Display tree
    		t.inorderWalk();
    
    		// Search
    		System.out.println(t.search(7));//true
    		System.out.println(t.search(20));//false
    
    		// Min
    		System.out.println("Min: "+t.min());//1
    
    		// Max
    		System.out.println("Max: "+t.max());//15
    
    		// Height
    		System.out.println("Height: "+t.height());//4
    
    		// Successor
    		System.out.println("Successor: "+t.successor(3));//4
    		System.out.println("Successor: "+t.successor(7));//8
    		System.out.println("Successor: "+t.successor(8));//10
    		System.out.println("Successor: "+t.successor(15));//-1
    
    		// Predecessor
    		System.out.println("Predecessor: "+t.predecessor(13));//10
    		System.out.println("Predecessor: "+t.predecessor(10));//8
    		System.out.println("Predecessor: "+t.predecessor(8));//7
    		System.out.println("Predecessor: "+t.predecessor(1));//-1
    
    		//delete
    		t.delete(3);
    		t.inorderWalk();
    	}
    }
    			
    Reference