-
-
Notifications
You must be signed in to change notification settings - Fork 0
SkipList
Probabilistic ordered container with expected O(log n) search, insert, and remove. A skip list is a stack of ever-sparser singly linked lanes over a doubly linked bottom lane: searches start at the top lane and drop down, skipping large runs of nodes. Unlike SplayTree, reads do not mutate the structure and performance does not depend on access patterns.
Legend for tables
-
API
-
options- an object with optional properties:-
less(a, b)- a function prototyped asa < b(the default) -
compare(a, b)- a function prototyped asa - b. See Array.prototype.sort() for more info. Default:null.- If specified, it overrides
less.
- If specified, it overrides
-
p- probability of promoting a node one level up. Default:0.5. -
maxLevel- maximum tower height. Default:32. -
random()- random source returning numbers in[0, 1). Default:Math.random. Inject for deterministic behavior (e.g., tests).
-
-
value- the value to be stored in the list -
range- an object with optional inclusive value bounds:fromandto
-
-
Complexity
- O - complexity of an operation
- O(1) - constant time
- O(log n) - expected logarithmic time (with high probability)
- O(k) - linear time proportional to the argument size
Implementation of SkipList.
import SkipList from 'list-toolkit/skip-list.js';
const list = SkipList.from([5, 3, 7, 1, 4]);
for (const value of list) console.log(value); // 1, 3, 4, 5, 7
console.log(list.floor(6).value); // 5
console.log(list.ceil(6).value); // 7
for (const value of list.getIterator({from: 3, to: 5})) console.log(value); // 3, 4, 5Properties: value, next (array of forward pointers, index 0 is the bottom lane), prev (previous node on the bottom lane), level (tower height).
Methods:
| Member | Return type | Description | O |
|---|---|---|---|
constructor(options) |
SkipList |
Create a new skip list. | O(1) |
size |
number | The number of elements. | O(1) |
length |
number | The number of elements. An alias of size. |
O(1) |
isEmpty |
truthy/falsy | Checks if the skip list is empty. | O(1) |
compare |
function | null | Comparator from options (or null if less is used). |
O(1) |
less |
function | Less-than function (derived from compare if given). |
O(1) |
getMin() |
SkipListNode | null
|
The node with the minimum value. | O(1) |
getMax() |
SkipListNode | null
|
The node with the maximum value. | O(1) |
find(value) |
SkipListNode | null
|
Find the node with the specified value. | O(log n) |
has(value) |
boolean | Check if the value is present. | O(log n) |
floor(value) |
SkipListNode | null
|
The node with the greatest value ≤ value. |
O(log n) |
ceil(value) |
SkipListNode | null
|
The node with the smallest value ≥ value. |
O(log n) |
insert(value) |
this |
Insert the value. Duplicates are ignored. | O(log n) |
remove(value) |
this |
Remove the value. Missing values are ignored. | O(log n) |
popFront() |
value | undefined
|
Remove and return the minimum value. | O(1) |
clear() |
this |
Clear the skip list. | O(1) |
[Symbol.iterator]() |
iterator | Iterate over values in ascending order. | O(1) |
getIterator(range) |
iterable | Iterate over values within the inclusive range. | O(log n) |
getNodeIterator(range) |
iterable | Iterate over nodes within the inclusive range. | O(log n) |
getReverseIterator() |
iterable | Iterate over values in descending order. | O(1) |
Static members:
| Member | Return type | Description | O |
|---|---|---|---|
from(values, options) |
SkipList |
Create a skip list from an iterable. | O(k log k) |
defaults |
object | Default {less, compare, p, maxLevel, random} options. |
O(1) |
All logarithmic bounds are expected (with high probability), not worst-case — the structure is randomized. The defaults (p = 0.5, maxLevel = 32) comfortably cover billions of elements.
popFront() makes the skip list usable as a priority queue with unique priorities; unlike heap-based queues, the whole queue is iterable in order at any moment.
getIterator({from, to}) and getNodeIterator({from, to}) yield elements in [from, to] (both bounds inclusive and optional) — a cheap ordered range scan that SplayTree does not offer.
Reads (find, has, floor, ceil, iteration) never mutate the structure, making the skip list preferable to a splay tree for read-mostly workloads and shared data. A splay tree remains preferable when access patterns are highly skewed and its move-to-root locality pays off.
SkipList is the default export. SkipList and SkipListNode are also exported by name.
Concepts
DLL: doubly linked lists
SLL: singly linked lists
Unrolled list
List utilities
Caches
Heaps
Queue, Stack, and Deque
Trees
Skip list
Timer wheel
Free list