/// <summary> /// Removes all the empty levels leftover in the Skip List /// </summary> protected void clearEmptyLevels() { if (this.levels > 1) //more than one level, don't want to remove bottom level { SkipListNode <T> currentNode = this.topLeft; while (currentNode != this.bottomLeft) //do not remove the bottom level { if (currentNode.IsHeader() && currentNode.Next.IsFooter()) { SkipListNode <T> belowNode = currentNode.Below; //Remove the empty level //Update pointers topLeft = currentNode.Below; //Remove links currentNode.Next.Dispose(); currentNode.Dispose(); //Update counters this.levels--; currentNode = belowNode; //scan down } else { break; //a single non-emtpy level means the rest of the levels are not empty } } } }
/// <summary> /// Removes a value or node from the Skip List /// </summary> public virtual bool Remove(SkipListNode <T> valueNode) { if (valueNode == null) { return(false); } else { //Make sure node is top-level node in it's tower if (valueNode.Above != null) { valueNode = this.FindHighest(valueNode); } //---Delete nodes going down the tower SkipListNode <T> currentNodeDown = valueNode; while (currentNodeDown != null) { //Remove right-left links SkipListNode <T> previousNode = currentNodeDown.Previous; SkipListNode <T> nextNode = currentNodeDown.Next; //Link the previous and next nodes to each other previousNode.Next = nextNode; nextNode.Previous = previousNode; SkipListNode <T> belowNode = currentNodeDown.Below; //scan down currentNodeDown.Dispose(); //unlink previous currentNodeDown = belowNode; } //update counter this.size--; //Clean up the Skip List by removing levels that are now empty this.clearEmptyLevels(); return(true); } }