Exemple #1
0
        /// <summary>
        /// Delete the node from the tree.
        /// Update the related wires, and update the median.
        /// According to the book page 221 it's O(h)
        /// </summary>
        /// <param name="node">Node for delete</param>
        public void Delete(T node)
        {
            if (node == null)
            {
                return;
            }
            var deletedTheOldMedian = false;

            UpdateWiresRelatedToRemovedNode(node);

            // If we delete the current median, the counters are already updated
            // so we can update it now.
            if (node.Id == Median.Id)
            {
                UpdateMedianAfterMedianDelete();
                deletedTheOldMedian = true;
            }

            AbstractNode nodeForRemove, nextNode = null;

            if (!node.HasALeftChild() || !node.HasARightChild())
            {
                nodeForRemove = node;
            }
            else
            {
                nodeForRemove = node.GetSuccessor();
            }

            if (nodeForRemove.HasALeftChild())
            {
                nextNode = nodeForRemove.LeftChild;
            }
            else if (nodeForRemove.HasARightChild())
            {
                nextNode = nodeForRemove.RightChild;
            }

            if (nextNode != null)
            {
                nextNode.Parent = nodeForRemove.Parent;
            }

            if (nodeForRemove.Parent == null)
            {
                Root = nextNode as T;
            }
            else
            {
                if (nodeForRemove.Id == nodeForRemove.Parent.LeftChild.Id)
                {
                    nodeForRemove.Parent.LeftChild = nextNode;

                    // If after this change, the parent gets a "null child"
                    // instead of the delete node, wire it to predecessor
                    if (nodeForRemove.Parent.LeftChild == null)
                    {
                        nodeForRemove.Parent.LeftChild = nodeForRemove.Parent.GetPredecessor();
                    }
                }
                else
                {
                    nodeForRemove.Parent.RightChild = nextNode;

                    // If after this change, the parent gets a "null child"
                    // instead of the delete node, wire it to successor
                    if (nodeForRemove.Parent.RightChild == null)
                    {
                        nodeForRemove.Parent.RightChild = nodeForRemove.Parent.GetSuccessor();
                    }
                }
            }

            if (nodeForRemove.Id != node.Id)
            {
                node.Clone(nodeForRemove);
            }

            // If we deleted another node(not the median), update the median
            // if needed
            if (!deletedTheOldMedian)
            {
                UpdateMedianAfterRemoveNotMedian(node);
            }
        }
 protected AbstractNode(int id)
 {
     Id     = id;
     Parent = null;
 }