/// <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; }