private MyAVLNode Find(int target, MyAVLNode current)
 {
     if (target < current.Data)
     {
         if (target == current.Data)
         {
             return(current);
         }
         else
         {
             return(Find(target, current.leftChild));
         }
     }
     else
     {
         if (target == current.Data)
         {
             return(current);
         }
         else
         {
             return(Find(target, current.rightChild));
         }
     }
 }
        private MyAVLNode balance_tree(MyAVLNode current)
        {
            int b_factor = balance_factor(current);

            if (b_factor > 1)
            {
                if (balance_factor(current.leftChild) > 0)
                {
                    current = RotateLL(current);
                }
                else
                {
                    current = RotateLR(current);
                }
            }
            else if (b_factor < -1)
            {
                if (balance_factor(current.rightChild) > 0)
                {
                    current = RotateRL(current);
                }
                else
                {
                    current = RotateRR(current);
                }
            }
            return(current);
        }
        private MyAVLNode RotateRL(MyAVLNode parent)
        {
            MyAVLNode pivot = parent.rightChild;

            parent.rightChild = RotateLL(pivot);
            return(RotateRR(parent));
        }
        private MyAVLNode RotateLL(MyAVLNode parent)
        {
            MyAVLNode pivot = parent.leftChild;

            parent.leftChild = pivot.rightChild;
            pivot.rightChild = parent;
            return(pivot);
        }
        private int balance_factor(MyAVLNode current)
        {
            int l        = getHeight(current.leftChild);
            int r        = getHeight(current.rightChild);
            int b_factor = l - r;

            return(b_factor);
        }
 private void PostOrderDisplayTree(MyAVLNode current)
 {
     if (current != null)
     {
         PostOrderDisplayTree(current.leftChild);
         PostOrderDisplayTree(current.rightChild);
         Console.Write("{0} ", current.Data);
     }
 }
        public void Add(int data)
        {
            MyAVLNode newItem = new MyAVLNode(data);

            if (root == null)
            {
                root = newItem;
            }
            else
            {
                root = RecursiveInsert(root, newItem);
            }
        }
        private int getHeight(MyAVLNode current)
        {
            int height = 0;

            if (current != null)
            {
                int l = getHeight(current.leftChild);
                int r = getHeight(current.rightChild);
                int m = max(l, r);
                height = m + 1;
            }
            return(height);
        }
 private MyAVLNode RecursiveInsert(MyAVLNode current, MyAVLNode n)
 {
     if (current == null)
     {
         current = n;
         return(current);
     }
     else if (n.Data < current.Data)
     {
         current.leftChild = RecursiveInsert(current.leftChild, n);
         current           = balance_tree(current);
     }
     else if (n.Data > current.Data)
     {
         current.rightChild = RecursiveInsert(current.rightChild, n);
         current            = balance_tree(current);
     }
     return(current);
 }
        private MyAVLNode RemoveX(MyAVLNode current, int target)
        {
            MyAVLNode parent;

            if (current == null)
            {
                return(null);
            }
            else
            {
                //left subtree
                if (target < current.Data)
                {
                    current.leftChild = RemoveX(current.leftChild, target);
                    if (balance_factor(current) == -2)//here
                    {
                        if (balance_factor(current.rightChild) <= 0)
                        {
                            current = RotateRR(current);
                        }
                        else
                        {
                            current = RotateRL(current);
                        }
                    }
                }
                //right subtree
                else if (target > current.Data)
                {
                    current.rightChild = RemoveX(current.rightChild, target);
                    if (balance_factor(current) == 2)
                    {
                        if (balance_factor(current.leftChild) >= 0)
                        {
                            current = RotateLL(current);
                        }
                        else
                        {
                            current = RotateLR(current);
                        }
                    }
                }
                //if target is found
                else
                {
                    if (current.rightChild != null)
                    {
                        //delete its inorder successor
                        parent = current.rightChild;
                        while (parent.leftChild != null)
                        {
                            parent = parent.leftChild;
                        }
                        current.Data       = parent.Data;
                        current.rightChild = RemoveX(current.rightChild, parent.Data);
                        if (balance_factor(current) == 2)//rebalancing
                        {
                            if (balance_factor(current.leftChild) >= 0)
                            {
                                current = RotateLL(current);
                            }
                            else
                            {
                                current = RotateLR(current);
                            }
                        }
                    }
                    else
                    {   //if current.left != null
                        return(current.leftChild);
                    }
                }
            }
            return(current);
        }
 public void RemoveX(int target)
 {
     root = RemoveX(root, target);
 }