Ejemplo n.º 1
0
        private void Remove(T value, Node <T> currentNode)
        {
            if (currentNode == null)
            {
                return;
            }

            int compResult = value.CompareTo(currentNode.value);

            if (compResult == 0)
            {
                bool     isLeftChild = currentNode.parent.left != null && currentNode.Equals(currentNode.parent.left);
                Node <T> newParentRef;

                //if there's no right branch
                if (currentNode.right == null)
                {
                    //if it's a leaf node
                    if (currentNode.left == null)
                    {
                        newParentRef = null;
                    }
                    else
                    {
                        newParentRef            = currentNode.left;
                        currentNode.left.parent = currentNode.parent;
                    }
                }
                else
                {
                    Node <T> replacement = GetNextMinNode(currentNode.right);

                    //Reset old parent's link to replacement node
                    if (replacement.parent.left != null && replacement.parent.left.Equals(replacement))
                    {
                        replacement.parent.left = null;
                    }
                    else
                    {
                        replacement.parent.right = null;
                    }

                    newParentRef       = replacement;
                    replacement.parent = currentNode.parent;
                    replacement.left   = currentNode.left;

                    if (currentNode.left != null)
                    {
                        currentNode.left.parent = replacement;
                    }

                    if (replacement.right == null)
                    {
                        replacement.right = currentNode.right;
                    }
                }

                if (isLeftChild)
                {
                    currentNode.parent.left = newParentRef;
                }
                else
                {
                    currentNode.parent.right = newParentRef;
                }
            }
            else if (compResult > 0)
            {
                Remove(value, currentNode.right);
            }
            else
            {
                Remove(value, currentNode.left);
            }
        }
        public void DeleteNode(Node <T> NodeToDelete)
        {
            //No children -> Just Delete
            if (NodeToDelete.HasNoChildren())
            {
                if (NodeToDelete.Equals(Root))
                {
                    Root = null;
                    return;
                }

                Traverse((Node <T> node) =>
                {
                    if (node.Left != null)
                    {
                        if (node.Left.Equals(NodeToDelete))
                        {
                            node.Left = null;
                        }
                    }
                    if (node.Right != null)
                    {
                        if (node.Right.Equals(NodeToDelete))
                        {
                            node.Right = null;
                        }
                    }
                }, TraversalType.PostOrder);
                return;
            }

            //Exactly one child -> Swap
            if (NodeToDelete.HasOneChild())
            {
                if (NodeToDelete.Equals(Root))
                {
                    Root = Root.Child();
                    return;
                }

                Traverse((Node <T> node) =>
                {
                    if (node.Left != null)
                    {
                        if (node.Left.Equals(NodeToDelete))
                        {
                            node.Left = NodeToDelete.Child();
                        }
                    }
                    if (node.Right != null)
                    {
                        if (node.Right.Equals(NodeToDelete))
                        {
                            node.Right = NodeToDelete.Child();
                        }
                    }
                }, TraversalType.PostOrder);

                return;
            }

            //Find Minimum of Right sub-Tree, Copy Value, Delete Minimum
            if (NodeToDelete.HasTwoChildren())
            {
                Node <T> SuccessorNode = MinValue(NodeToDelete.Right);
                NodeToDelete.Value = SuccessorNode.Value;
                DeleteNode(SuccessorNode);

                return;
            }
        }