예제 #1
0
 private void RightLeftRotate(AVLTreeNode <T> parent)
 {
     //parent must have a right child and a right-left grandchild
     RightRotate(parent.rightChild);
     LeftRotate(parent);
 }
예제 #2
0
 private void LeftRightRotate(AVLTreeNode <T> parent)
 {
     //parent must have a left child and a left-right grandchild
     LeftRotate(parent.leftChild);
     RightRotate(parent);
 }
예제 #3
0
        private bool RemoveCurrentNode(AVLTreeNode <T> node, bool isLeft, bool removeAll = false)
        {
            if (node.weight > 1)
            {
                if (removeAll)
                {
                    for (int i = 0; i < node.weight - 1; i++)
                    {
                        node.weight--;
                        MinusParentChildrenNum(node);
                    }
                }
                else
                {
                    node.weight--;
                    MinusParentChildrenNum(node);
                    return(true);
                }
            }

            if (node.leftChild == null)
            {
                var parent = node.parent;
                if (node.rightChild != null)
                {
                    node.rightChild.parent = parent;
                }

                if (parent == null)
                {
                    //root node
                    root = node.rightChild;
                }
                else
                {
                    if (isLeft)
                    {
                        parent.leftChild = node.rightChild;
                    }
                    else
                    {
                        parent.rightChild = node.rightChild;
                    }
                }
                MinusParentChildrenNum(node);
                BalanceNode(node.parent);
                node = null;//Memory Leak??
            }
            else if (node.rightChild == null)
            {
                var parent = node.parent;
                if (node.leftChild != null)
                {
                    node.leftChild.parent = parent;
                }

                if (parent == null)
                {
                    //root node
                    root = node.leftChild;
                }
                else
                {
                    if (isLeft)
                    {
                        parent.leftChild = node.leftChild;
                    }
                    else
                    {
                        parent.rightChild = node.leftChild;
                    }
                }
                MinusParentChildrenNum(node);
                BalanceNode(node.parent);
                node = null;
            }
            else
            {
                //Get the next node in InOrderTraverse
                var nextNode = GetNextInOrderNode(node);

                if (nextNode.parent == node)
                {
                    if (node.parent == null)
                    {
                        //root node
                        root            = nextNode;
                        nextNode.parent = null;
                    }
                    else
                    {
                        var parent = node.parent;
                        nextNode.parent = parent;

                        if (isLeft)
                        {
                            parent.leftChild = nextNode;
                        }
                        else
                        {
                            parent.rightChild = nextNode;
                        }
                    }
                    nextNode.leftChild = node.leftChild;
                    if (node.leftChild != null)
                    {
                        node.leftChild.parent = nextNode;
                        nextNode.childrenNum += node.leftChild.childrenNum + node.leftChild.weight;
                    }

                    MinusParentChildrenNum(nextNode);
                    BalanceNode(nextNode);
                    node = null;
                }
                else
                {
                    //Copy the value of nextNode to currentNode, then delete nextNode
                    node.data   = nextNode.data;
                    node.weight = nextNode.weight;
                    nextNode.parent.leftChild = nextNode.rightChild;
                    if (nextNode.rightChild != null)
                    {
                        nextNode.rightChild.parent = nextNode.parent;
                    }
                    MinusParentChildrenNum(nextNode, node, nextNode.weight);
                    UpdateChildrenNumberByDirectChildren(node);
                    BalanceNode(nextNode.parent);
                    nextNode = null;
                }
            }
            return(true);
        }
예제 #4
0
        private void BalanceNode(AVLTreeNode <T> newNode)
        {
            if (newNode == null)
            {
                return;
            }
            var currentNode      = newNode;
            var parent           = newNode;
            var isChildLeft      = true;
            var isGrandchildLeft = true;

            while (parent != null)
            {
                if (parent.leftChild == currentNode)
                {//Left Child
                    parent.leftHeight = Math.Max(currentNode.leftHeight, currentNode.rightHeight) + 1;
                }
                else if (parent.rightChild == currentNode)
                {//Right Child
                    parent.rightHeight = Math.Max(currentNode.leftHeight, currentNode.rightHeight) + 1;
                }
                else
                {//First time
                    if (parent.leftChild != null)
                    {
                        parent.leftHeight = Math.Max(parent.leftChild.leftHeight, parent.leftChild.rightHeight) + 1;
                    }
                    else
                    {
                        parent.leftHeight = 0;
                    }
                    if (parent.rightChild != null)
                    {
                        parent.rightHeight = Math.Max(parent.rightChild.leftHeight, parent.rightChild.rightHeight) + 1;
                    }
                    else
                    {
                        parent.rightHeight = 0;
                    }
                }

                var diff = parent.leftHeight - parent.rightHeight;
                if (diff >= 2 || diff <= -2)
                {
                    if (parent.leftHeight > parent.rightHeight)
                    {
                        isChildLeft = true;
                        //The balance of sub tree may be 0 on a deletion. Do not double-rotate in this case.
                        if (parent.leftChild.leftHeight >= parent.leftChild.rightHeight)
                        {
                            isGrandchildLeft = true;
                        }
                        else
                        {
                            isGrandchildLeft = false;
                        }
                    }
                    else
                    {
                        isChildLeft = false;
                        if (parent.rightChild.leftHeight > parent.rightChild.rightHeight)
                        {
                            isGrandchildLeft = true;
                        }
                        else
                        {
                            isGrandchildLeft = false;
                        }
                    }
                    Rotate(parent, isChildLeft, isGrandchildLeft);
                }

                currentNode = parent;
                parent      = parent.parent;
            }
        }
예제 #5
0
        //O(LogN)
        public bool InsertNode(T data)
        {
            try
            {
                var newNode = new AVLTreeNode <T>()
                {
                    data = data
                };

                if (root == null)
                {
                    root = newNode;
                    return(true);
                }

                var currentNode = root;
                while (true)
                {
                    var compareResult = CompareNode(data, currentNode.data);
                    if (compareResult > 0)
                    {
                        currentNode.childrenNum++;
                        if (currentNode.rightChild == null)
                        {
                            currentNode.rightChild = newNode;
                            newNode.parent         = currentNode;
                            break;
                        }
                        else
                        {
                            currentNode = currentNode.rightChild;
                        }
                    }
                    else if (compareResult < 0)
                    {
                        currentNode.childrenNum++;
                        if (currentNode.leftChild == null)
                        {
                            currentNode.leftChild = newNode;
                            newNode.parent        = currentNode;
                            break;
                        }
                        else
                        {
                            currentNode = currentNode.leftChild;
                        }
                    }
                    else
                    {
                        currentNode.weight++;
                        return(true);
                    }
                }
                BalanceNode(newNode);

                return(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return(false);
        }