//Following methods are helper method for treeBalancing method
        //Should not be used anywhere else.

        #region Tree Balancing Helper methods

        /// <summary>
        ///     private helper method: Hook up the node with the tree after apply supplied rotation function rotation
        /// </summary>
        /// <param name="stack"> the stack used to retrace the node visited </param>
        /// <param name="node"> the node currently in processing</param>
        /// <param name="func"> the rotation function</param>
        private void HookUp(Stack <AvlNode <T> > stack, AvlNode <T> node, Func <AvlNode <T>, AvlNode <T> > func)
        {
            if (stack.Count > 0)
            {
                if (stack.Peek().Left != null && stack.Peek().Left.Data.CompareTo(node.Data) == 0)
                {
                    stack.Peek().Left = func(node);
                    return;
                }

                stack.Peek().Right = func(node);
                return;
            }

            Root = func(node);
        }
 /// <summary>
 ///     private helper method: calculate the balancing factor of given node
 /// </summary>
 /// <param name="node"> node need to calculate balancing factor</param>
 /// <returns></returns>
 private int GetBalancingFactor(AvlNode <T> node)
 {
     //no child, balancing factor is 0
     if (node.IsLeafNode())
     {
         return(0);
     }
     //has two child, balancing factor is height of left subtree - height of right subtree
     if (!node.HasOneChild())
     {
         return(node.Left.Height - node.Right.Height);
     }
     //only one child, return that child's height
     if (node.Left != null) //child on the left
     {
         return(node.Left.Height);
     }
     return(0 - node.Right.Height); //child on the right
 }
Beispiel #3
0
        /// <summary>
        ///     Insert new data into AVL Tree.
        ///     If data is actually inserted, method will return true.
        ///     If duplicate data is found, duplicate data will not be inserted and method will return false.
        /// </summary>
        /// <param name="data">The data intended to be insert into this AVL Tree.</param>
        /// <returns></returns>
        public override bool Insert(T data)
        {
            //handling an empty tree
            if (Root == null)
            {
                Root = new AvlNode <T>(data)
                {
                    Height = 1
                };
                TreeSize++;
                return(true);
            }

            var res     = true;
            var current = Root;

            // use stack keep record of traverse path
            var stack = new Stack <AvlNode <T> >();

            stack.Push(current);
            while (true)
            {
                // Data to be inserted is smaller then current node, go left
                if (data.CompareTo(current.Data) < 0)
                {
                    if (current.Left != null)
                    {
                        current = current.Left;
                        stack.Push(current);
                        continue;
                    }

                    // if has no left child, insert new node here
                    current.Left = new AvlNode <T>(data);
                    stack.Push(current.Left);
                    break;
                }

                // Duplicate data is not allowed in BST, if found, stop insertion and return false;
                if (data.CompareTo(current.Data) == 0)
                {
                    res = false;
                    break;
                }

                // Data to be inserted is bigger then current node, go right
                if (current.Right != null)
                {
                    current = current.Right;
                    stack.Push(current);
                    continue;
                }

                // If has no right child, insert new node here
                current.Right = new AvlNode <T>(data);
                stack.Push(current.Right);
                break;
            }

            if (res)
            {
                // if data inserted, increase tree size and balancing the tree
                TreeSize++;
                TreeBalancing(stack);
            }

            return(res);
        }
Beispiel #4
0
 /// <summary>
 ///     Constructor of AVLTree with root node's data specified
 ///     this constructor creates an AVLTree contains only root node which holds specified data
 /// </summary>
 /// <param name="data"> the actual data the root node should hold </param>
 public AvlTree(T data)
 {
     Root = new AvlNode <T>(data);
     TreeSize++;
 }