/// <summary> /// Returns the first node whose value matches the input value /// </summary> public virtual SkipListNode <T> Find(T value) { SkipListNode <T> foundNode = this.topLeft; //Look for the highest-level node with an element value matching the parameter value while (foundNode != null && foundNode.Next != null) { if (!foundNode.Next.IsFooter() && foundNode.Next.Value.CompareTo(value) < 0) //next node's value is still smaller { foundNode = foundNode.Next; //keep scanning across } else { if (!foundNode.Next.IsFooter() && foundNode.Next.Value.Equals(value)) //value found { foundNode = foundNode.Next; break; } else { foundNode = foundNode.Below; //element not in this level, scan down } } } return(foundNode); }
/// <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 } } } }
public void Dispose() { value = default(T); next = null; previous = null; above = null; previous = null; }
public SkipList() { topLeft = getEmptyLevel(); //create an empty level bottomLeft = topLeft; levels = 1; //update the level count size = 0; //no elements added random = new Random(); //used for adding new values }
/// <summary> /// Removes all values in the Skip List /// </summary> public virtual void Clear() { SkipListNode <T> currentNode = this.Head; while (currentNode != null) { SkipListNode <T> nextNode = currentNode.Next; //save reference to next node if (!currentNode.IsHeader() && !currentNode.IsFooter()) { this.Remove(currentNode); } currentNode = nextNode; } }
/// <summary> /// Returns the highest node on the first tower to match the input value /// </summary> public virtual SkipListNode <T> FindHighest(SkipListNode <T> valueNode) { if (valueNode == null) { return(null); } else { //Scan up to the highest level while (valueNode.Above != null) { valueNode = valueNode.Above; } return(valueNode); } }
/// <summary> /// Returns the lowest node on the first tower to match the input value /// </summary> public virtual SkipListNode <T> FindLowest(SkipListNode <T> valueNode) { if (valueNode == null) { return(null); } else { //Scan down to the lowest level while (valueNode.Below != null) { valueNode = valueNode.Below; } return(valueNode); } }
public bool MoveNext() { if (current == null) { current = this.skipList.Head.Next; //Head is header node, start after } else { current = current.Next; } if (current != null && current.IsFooter()) { current = null; //end of list } return(current != null); }
/// <summary> /// Gets the number of levels of a value in the Skip List /// </summary> public virtual int GetHeight(SkipListNode <T> valueNode) { int height = 0; SkipListNode <T> currentNode = valueNode; //Move all the way down to the bottom first while (currentNode.Below != null) { currentNode = currentNode.Below; } //Count going back up to the top while (currentNode != null) { height++; currentNode = currentNode.Above; } return(height); }
/// <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); } }
public void Reset() { current = null; }
public void Dispose() { current = null; }
/// <summary> /// Gets the number of levels of a value in the Skip List /// </summary> public virtual int GetHeight(T value) { SkipListNode <T> valueNode = this.FindLowest(value); return(this.GetHeight(valueNode)); }
/// <summary> /// Removes a value or node from the Skip List /// </summary> public virtual bool Remove(T value) { SkipListNode <T> valueNode = this.FindHighest(value); return(this.Remove(valueNode)); }
/// <summary> /// Returns the highest node on the first tower to match the input value /// </summary> public virtual SkipListNode <T> FindHighest(T value) { SkipListNode <T> valueNode = this.Find(value); return(this.FindHighest(valueNode)); }
/// <summary> /// Add a value to the Skip List /// </summary> public virtual void Add(T value) { int valueLevels = getRandomLevels(); //determine height of value's tower //Add levels to entire list if necessary int newLevelCount = valueLevels - this.levels; //number of levels missing while (newLevelCount > 0) { //Create new level SkipListNode <T> newLevel = getEmptyLevel(); //Link down newLevel.Below = this.topLeft; this.topLeft.Above = newLevel; this.topLeft = newLevel; //update reference to most top-left node //Update counters newLevelCount--; this.levels++; } //Insert the value in the proper position, creating as many levels as was randomly determined SkipListNode <T> currentNode = this.topLeft; SkipListNode <T> lastNodeAbove = null; //keeps track of the upper-level nodes in a tower int currentLevel = this.levels - 1; while (currentLevel >= 0 && currentNode != null) { if (currentLevel > valueLevels) //too high on the list, nothing would be added to this level { currentNode = currentNode.Below; //scan down currentLevel--; //going one level lower continue; //skip adding to this level } //Add the value to the current level //Find the biggest value on the current level that is less than the value to be added while (currentNode.Next != null) { if (!currentNode.Next.IsFooter() && currentNode.Next.Value.CompareTo(value) < 0) //smaller { currentNode = currentNode.Next; //keep scanning across } else { break; //the next node would be bigger than the value } } //Insert the value right after the node found SkipListNode <T> newNode = new SkipListNode <T>(value); newNode.Next = currentNode.Next; newNode.Previous = currentNode; newNode.Next.Previous = newNode; currentNode.Next = newNode; //Link down/up the tower if (lastNodeAbove != null) //is this node part of a tower? { lastNodeAbove.Below = newNode; newNode.Above = lastNodeAbove; } lastNodeAbove = newNode; //start/continue tower //Scan down currentNode = currentNode.Below; currentLevel--; } this.size++; //update count }