14- Skip Lists¶
Overview¶
Skip lists are a probabilistic data structure that extend linked lists with multiple layers to improve search, insertion, and deletion efficiency. They provide a simpler alternative to balanced trees while maintaining logarithmic average-case performance.
Analogy¶
Searching in a skip list is like flipping through a book in large chunks, then smaller chunks as you get closer to the target.
Another analogy: passing messages between buildings using flashlights—higher floors skip over lower buildings.
Key Properties¶
Proposed by William Pugh.
Probabilistic: node heights are randomly chosen.
Multi-level linked lists: each level contains a subset of nodes from the level below.
Supports efficient search, insertion, and deletion in expected O(log n) time.
Randomized vs Deterministic¶
Deterministic structures always produce the same shape from the same data (e.g., BSTs, heaps, tries).
Randomized structures vary their structure probabilistically.
Randomization reduces worst-case scenarios and balances the average case.
Example: inserting nodes with random levels instead of always deterministic placement.
Skip List Structure¶
SkipList¶
SkipList
{
Integer: top_level # highest level in use
Integer: max_level # maximum allowable level
SkipListNode: front # dummy node at front
}
SkipListNode¶
SkipListNode
{
Type: key
Type: value
Integer: height
Array of SkipListNodes: next # pointers for each level [0, height]
}
Higher-level nodes have fewer nodes but longer skips.
front node simplifies insertion/deletion by tracking top-level pointers.
Searching¶
Algorithm¶
SkipListSearch(SkipList: list, Type: target):
level = list.top_level
current = list.front
while level >= 0:
while current.next[level] != null and current.next[level].key < target:
current = current.next[level]
level -= 1
result = current.next[0]
if result != null and result.key == target:
return result.value
else:
return null
Start at top-left (highest level, front node).
Move right while next key < target.
Drop down a level if no more progress.
Repeat until bottom level reached.
Insertion¶
Algorithm¶
SkipListInsert(SkipList: list, Type: key, Type: value):
level = list.top_level
current = list.front
last = array of size list.max_level + 1, initialized with list.front
while level >= 0:
while current.next[level] != null and current.next[level].key < key:
current = current.next[level]
last[level] = current
level -= 1
result = current.next[0]
if result != null and result.key == key:
result.value = value
return
new_level = pick_random_level()
if new_level > list.top_level:
list.top_level = new_level
new_node = SkipListNode(key, value, new_level)
for j in range(new_level + 1):
new_node.next[j] = last[j].next[j]
last[j].next[j] = new_node
Use same traversal logic as search.
Track last node at each level (last) to update pointers.
Assign node a random height using probability p (commonly 0.5).
Insert node into each level up to its height.
Deletion¶
Algorithm¶
SkipListDelete(SkipList: list, Type: target):
level = list.top_level
current = list.front
last = array of size list.max_level + 1, initialized with list.front
while level >= 0:
while current.next[level] != null and current.next[level].key < target:
current = current.next[level]
last[level] = current
level -= 1
result = current.next[0]
if result == null or result.key != target:
return
for j in range(result.height + 1):
last[j].next[j] = result.next[j]
result.next[j] = null
if result.height == list.top_level:
top = list.top_level
while top > 0 and list.front.next[top] == null:
top -= 1
list.top_level = top
Mirrors insertion logic for traversal.
Update pointers at each level to skip over the deleted node.
Adjust top_level if the tallest node was removed.
Node Height Selection¶
All nodes start at level 0.
Randomly decide to promote node to next level with probability p.
Maximum height capped by max_level.
Expected distribution: half of level L nodes appear at level L+1 (if p = 0.5).
Performance¶
Average-case search, insert, delete: O(log n)
Worst-case (all nodes same height): O(n)
Expected behavior mirrors balanced binary search trees.
Why Skip Lists Matter¶
Simpler than balanced search trees.
Randomized structure provides robust average-case performance.
Demonstrates the use of probabilistic structures for efficient algorithms.