예제 #1
0
파일: AvlTree.cs 프로젝트: radtek/datawf
        public bool Remove(IAvlNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            var left   = node.Left;
            var right  = node.Right;
            var parent = node.Parent;

            if (left == null)
            {
                if (right == null)
                {
                    if (node == Root)
                    {
                        Clear();
                        return(true);
                    }
                    if (parent == null)
                    {
                        throw new Exception();
                    }
                    if (parent.Left == node)
                    {
                        parent.Left = null;
                        DeleteBalanceTree(parent, 1);
                    }
                    else
                    {
                        parent.Right = null;
                        DeleteBalanceTree(parent, -1);
                    }
                }
                else
                {
                    if (node == Root)
                    {
                        node.Right.Parent = null;
                        Root = (T)node.Right;
                        return(true);
                    }
                    node.Right.Parent = node.Parent;
                    if (parent.Left == node)
                    {
                        parent.Left = node.Right;
                        DeleteBalanceTree(parent, 1);
                    }
                    else
                    {
                        parent.Right = node.Right;
                        DeleteBalanceTree(parent, -1);
                    }
                }
            }
            else if (right == null)
            {
                if (node == Root)
                {
                    node.Left.Parent = null;
                    Root             = (T)node.Left;
                    return(true);
                }
                node.Left.Parent = node.Parent;
                if (parent.Left == node)
                {
                    parent.Left = node.Left;
                    DeleteBalanceTree(parent, 1);
                }
                else
                {
                    parent.Right = node.Left;
                    DeleteBalanceTree(parent, -1);
                }
            }
            else
            { // no (half-)leaf
                IAvlNode successor;
                if (node.Balance > -1)
                {
                    successor = node.AvlGetNextNode();
                }
                else
                {
                    successor = node.AvlGetPrevNode();
                }
                SwitchNodes(node, successor);
                successor.UpdateAugmentedData();
                return(Remove(node));
            }
            if (parent != null)
            {
                parent.UpdateAugmentedData();
            }
            Count--;
            OnNodeRemoved(new TreeNodeEventArgs((T)node));
            return(true);
        }