public AVLNode(T val, AVLNode <T> leftNode = null, AVLNode <T> rightNode = null, AVLNode <T> parent = null)
 {
     this.val = val;
     left     = leftNode;
     right    = rightNode;
 }
 public AVLTree(T firstNodeVal)
 {
     topNode = new AVLNode <T>(firstNodeVal);
 }
/*        public IEnumerable<AVLNode<T>> InOrder()
 *      {
 *          AVLNode<T> tempNode = topNode;
 *          while (tempNode != null)
 *          {
 *              yield return tempNode;
 *
 *          }
 *      }
 */
        void RotationLoop(AVLNode <T> newItem)
        {
            var me = newItem;

            while (me != null)
            {
                if (me.Balance > 1)
                {
                    var child = me.right;

                    if (child.Balance >= 0)
                    {
                        //left rot!
                        Console.WriteLine("Doing a left rotation!");
                        child.right = me.right?.right;

                        if (me.right.right != null)
                        {
                            me.right.right.parent = child;
                        }

                        me.right = child.left;
                        if (child.left != null)
                        {
                            child.left.parent = me;
                        }

                        if (me.parent == null)
                        {
                            topNode = child;
                        }
                        else
                        {
                            if (me.parent.left == me)
                            {
                                me.parent.left = child;
                            }
                            else if (me.parent.right == me)
                            {
                                me.parent.right = child;
                            }
                            else
                            {
                                throw new Exception("Luke... I'm... Not... Your... Father!");
                            }
                        }
                        child.parent = me.parent;

                        child.left = me;
                        me.parent  = child;
                    }
                    else
                    {
                        //left right rot!
                        Console.WriteLine("Doing a left right rot!");
                        var grandchild      = child.left;
                        var greatchildright = grandchild.right;
                        grandchild.right = child;
                        child.parent     = grandchild;
                        child.left       = greatchildright;
                        if (greatchildright != null)
                        {
                            greatchildright.parent = child;
                        }
                        child        = grandchild;
                        me.right     = child;
                        child.parent = me;

                        //now rotate left

                        child.right = me.right?.right;
                        if (me.right.right != null)
                        {
                            me.right.right.parent = child;
                        }

                        me.right = child.left;
                        if (child.left != null)
                        {
                            child.left.parent = me;
                        }

                        if (me.parent == null)
                        {
                            topNode = child;
                        }
                        else
                        {
                            if (me.parent.left == me)
                            {
                                me.parent.left = child;
                            }
                            else if (me.parent.right == me)
                            {
                                me.parent.right = child;
                            }
                            else
                            {
                                throw new Exception("Luke... I'm... Not... Your... Father!");
                            }
                        }
                        child.parent = me.parent;
                        child.left   = me;
                        me.parent    = child;
                    }
                }
                if (me.Balance < -1)
                {
                    var child = me.left;


                    if (child.Balance <= 0)
                    {
                        //right rot!
                        Console.WriteLine("Doing a right rotation!");

                        child.left = me.left?.left;
                        if (me.left.left != null)
                        {
                            me.left.left.parent = child;
                        }
                        me.left = child.right;
                        if (child.right != null)
                        {
                            child.right.parent = me;
                        }


                        if (me.parent == null)
                        {
                            topNode = child;
                        }
                        else
                        {
                            if (me.parent.left == me)
                            {
                                me.parent.left = child;
                            }
                            else if (me.parent.right == me)
                            {
                                me.parent.right = child;
                            }
                            else
                            {
                                throw new Exception("Luke... I'm... Not... Your... Father!");
                            }
                        }
                        child.parent = me.parent;
                        child.right  = me;
                        me.parent    = child;
                    }
                    else
                    {
                        //right left rot!
                        Console.WriteLine("Doing a right left rot!");

                        var grandchild     = child.right;
                        var greatchildleft = grandchild.left;
                        grandchild.left = child;
                        child.parent    = grandchild;
                        child.right     = greatchildleft;
                        if (greatchildleft != null)
                        {
                            greatchildleft.parent = child;
                        }
                        child = grandchild;

                        me.left      = child;
                        child.parent = me;

                        //now rotate right
                        child.left = me.left?.left;
                        if (me.left.left != null)
                        {
                            me.left.left.parent = child;
                        }
                        me.left = child.right;
                        if (child.right != null)
                        {
                            child.right.parent = me;
                        }

                        if (me.parent == null)
                        {
                            topNode = child;
                        }
                        else
                        {
                            if (me.parent.left == me)
                            {
                                me.parent.left = child;
                            }
                            else if (me.parent.right == me)
                            {
                                me.parent.right = child;
                            }
                            else
                            {
                                throw new Exception("Luke... I'm... Not... Your... Father!");
                            }
                        }
                        child.parent = me.parent;
                        child.right  = me;
                        me.parent    = child;
                    }
                }
                me = me.parent;
            }
        }
 public AVLTree()
 {
     topNode = null;
 }