Ejemplo n.º 1
0
        /// <summary>
        /// Perform rightleft rotation with owerweght node
        /// </summary>
        /// <param name="overweight"></param>
        /// <returns>Rebalanced node</returns>
        private Node <T> RLRotation(NodeAVL <T> overweight)
        {
#if DEBUG
            RLrotations++;
#endif
            Node <T> N = overweight;
            Node <T> B = overweight.Right;
            Node <T> F = overweight.Right.Left;
            //(1)
            if (N.Parent == null)
            {
                Root = F;
            }
            else if (N < N.Parent)
            {
                N.Parent.Left = F;
            }
            else if (N > N.Parent)
            {
                N.Parent.Right = F;
            }
            //(8)
            F.Parent = N.Parent;
            //(10)
            N.Parent = F;
            //(5) save T3
            Node <T> tempNode = F.Right;
            F.Right = B;
            //(9)
            B.Parent = F;
            //(3)
            B.Left = tempNode;
            //(7) T3 don't necessary exist
            if (B.Left != null)
            {
                B.Left.Parent = B;
            }
            //(2) new parent
            N.Right = F.Left;
            //(6)  T2 don't necessary exist
            if (N.Right != null)
            {
                N.Right.Parent = N;
            }
            //(4) new parent
            F.Left = N;

            RecalculateHeight((NodeAVL <T>)N);
            RecalculateHeight((NodeAVL <T>)B);
            if (((NodeAVL <T>)B).GetBalanceFactor() > 1)
            {
                RebalanceNode((NodeAVL <T>)B);
#if DEBUG
                recursionCounter++;
#endif
            }
            RecalculateHeight((NodeAVL <T>)F);

            return(N);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Find and delete node from the tree
        /// </summary>
        /// <param name="node">Node with same unique data identifier to be deleted</param>
        /// <returns>True if node was deleted, false if unique data identifier was not found in the tree</returns>
        protected bool Delete(NodeAVL <T> node)
        {
            Node <T> current;
            Node <T> deletedNode = base.Delete(node, out current);

            //Node not found
            if (deletedNode == null)
            {
                return(false);
            }
            //delete node had less than 2 children
            if (current == null)
            {
                current = deletedNode;
            }
            else
            {
                RecalculateHeight((NodeAVL <T>)current);
            }
            while (current != null)
            {
                //current father no longer have pointer to current because it has been removed
                //if coming from right side, left side is getting bigger in height
                RebalanceNode(current);
#if DEBUG
                if (recursionCounter > 10)
                {
                    throw new Exception("Recursion called too much");
                }
                recursionCounter = 0;
#endif
                current = (NodeAVL <T>)current.Parent;
            }
            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// If tree doesnt contain node with same unique identifier, insert node to the tree
        /// </summary>
        /// <param name="node">Node with unique identifier to be inserted</param>
        /// <returns>False if comparator found node with same unique identifier,
        /// true otherwise</returns>
        protected bool Insert(NodeAVL <T> node)
        {
            //Node already exist return false
            if (!base.Insert(node))
            {
                return(false);
            }
            node.Height = 1;
            NodeAVL <T> current = (NodeAVL <T>)node.Parent;

            while (current != null)
            {
                RecalculateHeight(current);

                if (current.GetBalanceFactor() < -1)
                {
                    if (((NodeAVL <T>)current.Left)?.GetBalanceFactor() < 0)
                    {
                        RRotation(current);
                    }
                    else
                    {
                        LRRotation(current);
                    }

                    return(true);
                }
                else if (current.GetBalanceFactor() > 1)
                {
                    if (((NodeAVL <T>)current.Right)?.GetBalanceFactor() > 0)
                    {
                        LRotation(current);
                    }
                    else
                    {
                        RLRotation(current);
                    }

                    return(true);
                }
                if (current.GetBalanceFactor() == 0)
                {
                    return(true);
                }

                current = (NodeAVL <T>)current.Parent;
            }

            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Perform left rotation of nodes
        /// </summary>
        /// <param name="around">Hihgest node to rotate around</param>
        /// <returns>Rebalanced node</returns>
        private Node <T> LRotation(NodeAVL <T> around)
        {
#if DEBUG
            Lrotations++;
#endif
            Node <T> N = around;
            Node <T> B = around.Right;
            //N is overweight node ,B is right child of overweight node
            //change parent of N(1)
            if (N.Parent == null)
            {
                Root = B;
            }
            else if (N < N.Parent)
            {
                N.Parent.Left = B;
            }
            else if (N > N.Parent)
            {
                N.Parent.Right = B;
            }
            //change B parent to N parent (5)
            B.Parent = N.Parent;
            //(3) save T2
            Node <T> tempNode = B.Left;
            B.Left = N;
            //change parent of N to B (6)
            N.Parent = B;
            //change right child of N to right node of B (2)
            N.Right = tempNode;
            //change new N right child parent to N (4)
            //T2 can be null
            if (N.Right != null)
            {
                N.Right.Parent = N;
            }

            RecalculateHeight((NodeAVL <T>)N);
            RecalculateHeight((NodeAVL <T>)B);

            return(N);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Calculate height of node in the tree based of heigh of children elements
 /// </summary>
 /// <param name="node">Node which height is recalculated</param>
 protected void RecalculateHeight(NodeAVL <T> node)
 {
     node.Height = Math.Max(((NodeAVL <T>)node?.Right)?.Height ?? 0, ((NodeAVL <T>)node?.Left)?.Height ?? 0) + 1;
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Perform leftright rotation with owerweight node
        /// </summary>
        /// <param name="overweight"></param>
        /// <returns></returns>
        private Node <T> LRRotation(NodeAVL <T> overweight)
        {
#if DEBUG
            LRrotations++;
#endif
            Node <T> N = overweight;
            Node <T> B = overweight.Left;
            Node <T> F = overweight.Left.Right;
            //(1)
            if (N.Parent == null)
            {
                Root = F;
            }
            else if (N < N.Parent)
            {
                N.Parent.Left = F;
            }
            else if (N > N.Parent)
            {
                N.Parent.Right = F;
            }
            //(8)
            F.Parent = N.Parent;
            //(10)
            N.Parent = F;
            //(4) save T2
            Node <T> tempNode = F.Left;
            F.Left = B;
            //(9)
            B.Parent = F;
            //(3)
            B.Right = tempNode;
            //(6)
            if (B.Right != null)
            {
                B.Right.Parent = B;
            }
            //(2)
            N.Left = F.Right;
            //(7)
            if (N.Left != null)
            {
                N.Left.Parent = N;
            }
            //(5)
            F.Right = N;

            RecalculateHeight((NodeAVL <T>)N);
            RecalculateHeight((NodeAVL <T>)B);

            if (((NodeAVL <T>)B).GetBalanceFactor() < -1)
            {
                RebalanceNode((NodeAVL <T>)B);
#if DEBUG
                recursionCounter++;
#endif
            }

            RecalculateHeight((NodeAVL <T>)F);

            return(N);
        }