public SkipListNode(int size) { this.size = size; next = new SkipListNode[size]; distanceToNext = new int[size]; prev = null; }
/// <summary> /// Remove an entry in the map matching the specified key. /// </summary> /// <param name="key">The IComparable key to search for. If found the /// matching entry is removed from the map.</param> /// <returns>a bool indicating whether the specified key was found in /// the map and the entry removed</returns> public bool Remove(TKey key) { SkipListNode <TKey, TValue> position; bool found = search(key, out position); if (!found) { return(false); } else { SkipListNode <TKey, TValue> old = position; do { old.back.forward = old.forward; if (old.forward != null) { old.forward.back = old.back; } old = old.up; } while (old != null); count--; // Clean up rows with only a head remaining. while (head.forward == null) { head = head.down; } return(true); } }
public void PrintScoreTable(int id) { int i; SkipListNode n = position[id]; SkipListNode tmp = n; for (i = 0; i < 5; i++) { if (tmp.prev == head || tmp.prev == null) { break; } tmp = tmp.prev; //if (tmp.next[tmp.size - 1] == null) break; //tmp = tmp.next[tmp.size - 1]; } while (tmp != n) { Console.WriteLine(tmp.v); tmp = tmp.next[tmp.size - 1]; } Console.WriteLine(tmp.v); // print the one with the requested id tmp = tmp.next[tmp.size - 1]; for (i = 0; i < 4; i++) { if (tmp == null) { break; } Console.WriteLine(tmp.v); tmp = tmp.next[tmp.size - 1]; } }
public SkipListNode <T> AddNode(T val) { var newNode = new SkipListNode <T>(val, Promote()); if (newNode.Height > head.Height) { head.Resize(newNode.Height); } int level = head.Height - 1; SkipListNode <T> node = head; while (level >= 0) { if (node.next[level] == null || node.next[level].val.CompareTo(val) > 0) { if (level + 1 <= newNode.Height) { newNode.next[level] = node.next[level]; node.next[level] = newNode; } level--; } else { node = node.next[level]; } } return(newNode); }
/// <summary> /// This is an alternative (to indexing) interface to add and modify /// existing values in the map. /// </summary> /// <param name="key">The IComparable key</param> /// <param name="value">The new value</param> public void Add(TKey key, TValue value) { // Duh, we have to be able to tell when no key is found from when one is found // and if none is found have a reference to the last place searched.... return // a bool and use an out value? SkipListNode <TKey, TValue> position; bool found = search(key, out position); if (found) { position.value = value; } else { // In this scenario position, rather than the value we searched // for is the value immediately previous to where it should be inserted. SkipListNode <TKey, TValue> newEntry = new SkipListNode <TKey, TValue>((TKey)key, value); count++; newEntry.back = position; if (position.forward != null) { newEntry.forward = position.forward; } position.forward = newEntry; promote(newEntry); } }
public SkipListNode <T> FindNode(T val) { int level = head.Height - 1; SkipListNode <T> node = head; while (level >= 0) { if (node == null) { throw new Exception("Could not find node"); } if (node.val.CompareTo(val) == 0 && node != head) { return(node); } if (node.next[level] == null || node.next[level].val.CompareTo(val) > 0) { level--; } else { node = node.next[level]; } } throw new Exception("Could not find node"); }
public SkipListNode(int size, int k, int v) { prev = null; this.size = size; this.v = v; this.k = k; next = new SkipListNode[size]; distanceToNext = new int[size]; }
public void Resize(int size) { var tmp = new SkipListNode <T> [size]; for (int i = 0; i < next.Length; i++) { tmp[i] = next[i]; } next = tmp; }
public SkipList(List <T> originalList) { var iterator = new SkipListNode(originalList[0]); bottomHead = new Header { Next = iterator }; topHead = bottomHead; foreach (var element in originalList.Skip(1)) // general lvl creation { var newElement = new SkipListNode(element); iterator.Next = newElement; newElement.Previous = iterator; iterator = iterator.Next; } while (topHead.LevelSize > 2) // Sub-levels building { var newHeader = new Header(); newHeader.Below = topHead; topHead.Above = newHeader; SkipListNode upIterator = new SkipListNode(); iterator = topHead.Next; bool first = true; for (var i = 1; iterator != null; i++) // prev list iteration { if (i % 2 == 0) { if (first) { upIterator = new SkipListNode(iterator); newHeader.Next = upIterator; first = false; } else { var temp = new SkipListNode(iterator); upIterator.Next = temp; temp.Previous = upIterator; upIterator = upIterator.Next; } upIterator.Below = iterator; iterator.Above = upIterator; } iterator = iterator.Next; } topHead = newHeader; } }
/// <summary> /// Provides a System.Collections.Generic.IEnumerator<> interface to a /// collection of System.Collection.Generic.KeyValuePair<>s /// representing the entries in the map in key-sorted order. /// NOTE: The enumerator returned enumerates over internally used /// values, modifying the value is fine but do not modify the key /// because that would invalidate the internal structural assumptions. /// </summary> /// <returns>An IEnumerator<> of the map entries in key-sorted order</returns> public IEnumerator <KeyValuePair <TKey, TValue> > GetEnumerator() { SkipListNode <TKey, TValue> position = head; while (position.down != null) { position = position.down; } while (position.forward != null) { position = position.forward; yield return(new KeyValuePair <TKey, TValue>(position.key, position.value)); } }
/// <summary> /// Takes an Action that accepts one argument representing a /// SkipListNode in the map and performs the given action on every entry /// in the map in key-sorted order. /// </summary> /// <param name="lambda">A System.Action(T) that accepts one parameter /// which will be each unique entry as a SkipListNode</param> private void walkEntries(Action <SkipListNode <TKey, TValue> > lambda) { SkipListNode <TKey, TValue> node = head; while (node.down != null) { node = node.down; } while (node.forward != null) { node = node.forward; lambda(node); } }
public void printAll() { for (int i = 0; i < size; i++) { Console.WriteLine("Level " + i); for (SkipListNode n = head.next[i]; n != null;) { int myst = size - n.size; Console.Write(n.k + " "); n = n.next[i - myst]; } Console.WriteLine(); } }
public void printLvl(int lvl) { //for (int i = 0; i < size; i++) { Console.WriteLine("Level " + lvl); for (SkipListNode n = head.next[lvl]; n != null;) { //int prevst = size - n.size; int myst = size - n.size; Console.Write(n.k + " "); n = n.next[lvl - myst]; } Console.WriteLine(); } }
/// <summary> /// This algorithm promotes the newly added node on a probabilistic /// basis. /// </summary> /// <param name="node">The root node (initially added node added to the /// bottom, primary, row) to consider promoting.</param> private void promote(SkipListNode <TKey, TValue> node) { // up represents our search for the value just prior to the newly // added value in the next row to which the newly added value // should be promoted. // last represents the most recently added node, starting with the // newly created node. SkipListNode <TKey, TValue> up = node.back; SkipListNode <TKey, TValue> last = node; for (int levels = this.levels(); levels > 0; levels--) { // Find the next node back that links to next row up. // If we find our way back to the head of the row and there is // no link up then that means it is time to create a new row. while (up.up == null && !up.isFront) { up = up.back; } if (up.isFront && up.up == null) { // As mentioned above is this is the front of the row and // there is no link up then we need to start a new row and // update the head to ensure it always points to the start // of the topmost row. up.up = new SkipListNode <TKey, TValue>(); head = up.up; } up = up.up; // At this point up should represent the value in the next row // up immediately prior to where the new node should be // promoted. If this node has been promoted to a previously // unreached level, then up will be the head of the new row. SkipListNode <TKey, TValue> newNode = new SkipListNode <TKey, TValue>(node.keyValue); newNode.forward = up.forward; up.forward = newNode; // Remember last starts as the brand new node but should be // updated to always point to the representative node in // the previous row. newNode.down = last; newNode.down.up = newNode; last = newNode; } }
public override string ToString() { string[] levels = new string[head.next.Length]; levels[0] += "H "; for (int i = 1; i < levels.Length; i++) { levels[i] += "# "; } SkipListNode <T> currNode = head.next[0]; while (currNode != null) { levels[0] += currNode.val; levels[0] += " "; for (int i = 1; i < head.next.Length; i++) { if (i < currNode.next.Length) { levels[i] += "#"; for (int j = 0; j < currNode.val.ToString().Length; j++) { levels[i] += " "; } } else { levels[i] += " "; for (int j = 0; j < currNode.val.ToString().Length; j++) { levels[i] += " "; } } } currNode = currNode.next[0]; } string final = ""; for (int i = levels.Length - 1; i >= 0; i--) { final += levels[i]; final += "\n"; } return(final); }
/// <summary> /// The core search algorithm: Returns a SkipListPair of SkipListNodes /// representing the matching entry with the given IComparable key and /// the immediately preceding entry in the map on the fastlane in which /// the entry was found. /// </summary> /// <param name="key">The IComparable key for which to search</param> /// <param name="position">Either the matching node if the true is /// returned as the return value, or, if false is returned, the value /// just before where the new value could be inserted.</param> /// <returns>Whether or not the search for value was found.</returns> private bool search(TKey key, out SkipListNode <TKey, TValue> position) { if (key == null) { throw new ArgumentNullException("key"); } SkipListNode <TKey, TValue> current; position = current = head; while ((current.isFront || key.CompareTo(current.key) >= 0) && (current.forward != null || current.down != null)) { position = current; if (key.CompareTo(current.key) == 0) { return(true); } if (current.forward == null || key.CompareTo(current.forward.key) < 0) { if (current.down == null) { return(false); } else { current = current.down; } } else { current = current.forward; } } position = current; // If the matching value is found in the last position of the last row, we could end up here with a match. if (key.CompareTo(position.key) == 0) { return(true); } else { return(false); } }
public SkipList(int size, int nPositions) { nElements = 0; position = new SkipListNode[nPositions + 1]; this.size = size; rnd = new Random(666); head = new SkipListNode(size); prob = new double[size]; prev = new SkipListNode[size]; double currentProb = 1.0; for (int i = size - 1; i >= 0; i--) { prob[i] = currentProb; currentProb /= 2.0; } }
public int getIndex(int k) // K is in the skip list { int idx = 0; int lvl = 0; SkipListNode n = head; int internLvl = 0; while (true) { if (n.next[internLvl] == null) { lvl++; internLvl++; if (lvl == size) // last one... insert here { Console.WriteLine("Shouldn't happen!!!(" + k + ")"); // insert(k, v, internLvl); break; } } else if (n.next[internLvl].k == k) { return(idx + n.distanceToNext[internLvl]); } else if (n.next[internLvl].k > k) // advance { idx += n.distanceToNext[internLvl]; int newStart = n.size - n.next[internLvl].size; n = n.next[internLvl]; internLvl = internLvl - newStart;// correct the level for this node } else // go to next level or insert here! { lvl++; internLvl++; if (lvl == size) // insert here! { Console.WriteLine("Shouldn't happen V2.0!!!(" + k + ")"); break; } } } return(idx); }
public bool Contains(T val) { int level = head.Height - 1; SkipListNode <T> node = head; while (level >= 0) { if (node.next[level].val.Equals(val)) { return(true); } if (node.next[level] == null || node.next[level].val.CompareTo(val) > 0) { level--; } else { node = node.next[level]; } } return(false); }
public SkipListNode FindElement(T value) // Accessibility ??? { var searchedElement = new SkipListNode(); var headerSearcher = topHead; //find starter lvl while (headerSearcher.Next.Value.CompareTo(value) > 0 && headerSearcher.Below != null) { headerSearcher = headerSearcher.Below; } searchedElement = headerSearcher.Next; // find element while (searchedElement.Value.CompareTo(value) != 0) { if (searchedElement.Next != null && (searchedElement.Next.Value.CompareTo(value) < 0 || searchedElement.Next.Value.CompareTo(value) == 0)) { searchedElement = searchedElement.Next; } else { if (searchedElement.Below != null) { searchedElement = searchedElement.Below; } else { throw new ArgumentException("There is no such element in this collection"); } } } return(searchedElement); }
public void RemoveNode(T val) { SkipListNode <T> nodeToRemove = FindNode(val); int level = head.Height - 1; SkipListNode <T> node = head; while (level >= 0) { if (node == nodeToRemove) { return; } if (node == null) { throw new Exception("AAaaaAAaAAaAAAaaa its null"); } if (node.next[level] == nodeToRemove) { node.next[level] = nodeToRemove.next[level]; level--; continue; } if (node.next[level] == null || node.next[level].val.CompareTo(val) > 0) { level--; } else { node = node.next[level]; } } }
public void AddElement(T value) { var iterator = bottomHead.Next; bool firstChanged = false; while (true) // update bottom { if (value.CompareTo(iterator.Value) > 0 && iterator.Next != null) { iterator = iterator.Next; } else { var temp = new SkipListNode(value); if (iterator.Previous == null) { bottomHead.Next = temp; temp.Next = iterator; firstChanged = true; } else if (iterator.Next == null) { temp.Next = iterator.Next; iterator.Next = temp; temp.Previous = iterator; } else { temp.Next = iterator; temp.Previous = iterator.Previous; iterator.Previous.Next = temp; iterator.Previous = temp; } break; } } if (firstChanged) { var rnd = new Random(); var header = bottomHead.Above; while (header != null && rnd.NextDouble() > 0.5) { var newFirst = new SkipListNode(value); newFirst.Next = header.Next; header.Next.Previous = newFirst; header.Next = newFirst; header = header.Above; } } else { var rnd = new Random(); var previous = iterator.Next; while (iterator != null) { if (iterator.Above == null) { while (iterator != null && iterator.Above == null) { iterator = iterator.Previous; } } iterator = iterator.Above; if (rnd.NextDouble() > 0.5) { var newElement = new SkipListNode(value); newElement.Next = iterator.Next; newElement.Previous = iterator; iterator.Next = newElement; newElement.Below = previous; previous.Above = newElement; previous = newElement; iterator = iterator.Above; } else { break; } } } }
public SkipList() { head = new SkipListNode <T>(default(T), 0); }
/// <summary> /// Empty the skiplist. /// </summary> public void Clear() { head = new SkipListNode <TKey, TValue>(); count = 0; // Must more be done to ensure that all references are released? }
/// <summary> /// Creates and returns a new empty skiplist. /// </summary> public SkipList() { this.head = new SkipListNode <TKey, TValue>(); count = 0; }
void insert(int k, int n, int lvl) { int s = getRandomSize(); SkipListNode newNode = new SkipListNode(s, k, n); position[n] = newNode; for (int i = 0; i < s; i++) { int stprev = size - prev[size - s + i].size; int myst = size - s; newNode.next[i] = prev[size - s + i].next[myst - stprev + i]; prev[size - s + i].next[myst - stprev + i] = newNode; } newNode.prev = prev[size - 1]; if (newNode.next[s - 1] != null) { newNode.next[s - 1].prev = newNode; } int myIdx = newNode.prev == head ? 1 : getIndex(newNode.prev.k) + 1; for (int i = 0; i < s; i++) { int stprev = size - prev[size - s + i].size; int myst = size - s; int prevDist = prev[size - s + i].distanceToNext[myst - stprev + i]; //int distToThis = distance(prev[size - s + i], newNode); int idxPrev; if (prev[size - s + i] == head) { idxPrev = 0; } else { int kp = prev[size - s + i].k; idxPrev = getIndex(kp); } int distanceToMe = myIdx - idxPrev; if (newNode.next[i] == null) // this is the last node on this level { //if(prev[size-s+i]==head) idx //int kp = prev[size - s + i].k; //int idx = getIndex(kp); newNode.distanceToNext[i] = nElements - myIdx; prev[size - s + i].distanceToNext[myst - stprev + i] = distanceToMe; } else { int prevDistance = prev[size - s + i].distanceToNext[myst - stprev + i]; newNode.distanceToNext[i] = prevDistance - distanceToMe + 1; prev[size - s + i].distanceToNext[myst - stprev + i] = distanceToMe; // int idxPrev } } for (int i = 0; i < size - s; i++) { int stprev = size - prev[i].size; //int myst = size - s; prev[i].distanceToNext[i - stprev]++; } }
public SkipListNode(SkipListNode node) { Value = node.Value; }
int distance(SkipListNode a, SkipListNode b) { return(0); }
SkipListNode[] prev; // previous array public void insert(int k, int v) { nElements++; int i = 0; for (; i < size; i++) { if (head.next[i] != null) { break; } } if (i == size) // first node { head.next[i - 1] = new SkipListNode(1, k, v); position[v] = head.next[i - 1]; head.next[i - 1].distanceToNext[0] = 0; for (int j = 0; j < size; j++) { head.distanceToNext[j] = 1; } } else // find a spot to insert it { int lvl = 0; int internLvl = 0; SkipListNode n = head; while (true) { if (n.next[internLvl] == null) { prev[lvl] = n; lvl++; internLvl++; if (lvl == size) // last one... insert here { insert(k, v, internLvl); break; } } else if (n.next[internLvl].k == k) // same score... { // we don't insert, but we mark it n = n.next[internLvl]; position[v] = n; // update all distances for (i = 0; i < n.size; i++) { n.distanceToNext[i]++; } for (i = 0; i < size - n.size; i++) { int stprev = size - prev[i].size; prev[i].distanceToNext[i - stprev]++; } break; } else if (n.next[internLvl].k > k) // advance { prev[lvl] = n; int newStart = n.size - n.next[internLvl].size; n = n.next[internLvl]; internLvl = internLvl - newStart;// correct the level for this node } else // go to next level or insert here! { prev[lvl] = n; lvl++; internLvl++; if (lvl == size) // insert here! { insert(k, v, internLvl); break; } } } } }