Skip Lists
Skip lists are a variant of regular linked links that can allow for O(log n) search time. According to nist.gov’s Dictionary of Algorithms and Data Structures entry for Skip Lists, they are:
A randomized variant of an ordered linked list with additional, parallel lists. Parallel lists at higher levels skip geometrically more items. Searching begins at the highest level, to quickly get to the right part of the list, then uses progressively lower level lists. A new item is added by randomly selecting a level, then inserting it in order in the lists for that and all lower levels. With enough levels, searching is O(log n).
At a basic level, searching a skip list consists of starting at element i (where i = 0 to start) in level j in the list (where j is the highest level on the first iteration) and searching for your item. If you encouter a value that is greater than the value you are looking for, you move back to element i-1 in level j-1 and continue searching level j – 1. You continue this pattern until you find your element.
This process allows you to skip sections of the list that won’t contain your element (since skip lists are always sorted). Here’s a visual example:
1---------------5---------------* 1-------3-------5-------7-------* 1---2---3---4---5---6---7---8---*
Given this example, if you were searching for 8 you would only evaluate 4 elements, rather than 8 in a normal linked list. The sequence of evalution would go as follows:
1 -> 5 -> 7 -> 8
I won’t go into a lot of detail on the implementation of a skip list, but I’ll give a quick rundown of the basic and provide a couple links I found helpful.
The structure of the list is can be comprised of two parts, the list itself and nodes. I’ve taken the example from one of the sites listed below and kind of translated it into very rudimentary Ruby. At some point in the future, I might get around to writing some better ruby code, this is written for the sake of example.
class Node attr_accessor :height, :val, :next def initialize @height = 0 @val = 0 @next = Array.new end end class SkipList attr_accessor :height, :head def initialize @height = 0 @head = nil end def find( toFind ) node = @head # For each height, starting at the top... (@height..0).each do {|height| # Traverse the list from left to right at this height, # looking for the node who's next node is still smaller than # the value we're looking for while( !node.next[i].nil? && (toFind > node.next[i].val) ) { node = node.next[i] } } # By now, the next node should be the node we're looking for, nil, or # possibly greater than our node, but where our value should be return node.next[0].val end end
This only covers basic searching. There are algorithms for insertion, deletion and re-balancing the skip list as well. The page I’ve linked to below on Eternally Confuzzled covers some of these topics, and I hope to get to some of them in the future.
I found the following pages to be quite useful, I’m still reading up on Skip Lists so maybe I’ll have a nicer implementation available in the future:
- Skip List at Dictionary of Algorithms and Data Structures
- Skip Lists at Eternally Confuzzled, where I found sample implementations, a very nice write up
This entry was posted on Tuesday, May 5th, 2009 at 11:13 pm and is filed under Data and Algorithms. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

