skiplist 是組成有序集合(sort set)的重要數據結構
1. skiplist 圖示介紹
a. 單鏈表
b. 第二層中,第一層中每兩個元素,提取出一個元素。(可以跳躍個
c. 第三層中,以第二層爲基礎,第二層中每兩個元素,提取出一個元素。(可以跳躍
d.第四層中,以第三層爲基礎,第三層中每兩個元素,提取出一個元素。
(可以跳躍
e.最終一層層向上,每層的元素數量遞減,等比數列。類似於平衡樹結構。
具體元素組成的跳躍表
這樣標準的跳躍鏈表:其不難得出時間複雜度爲
但是維護這樣標準的跳躍表(上一層元素的數量是當前層元素數量的
因此採用隨機法來生成層級,每一個新的元素的層級都是隨機出來的。
最終生成的跳躍表可能如下圖所示:
每一層都可以看成是單鏈表,第一層包含所有的元素。
- skiplist算法
- 查找算法
查找19步驟:
a 從最高層即第三層開始
b 19比6大,向前移動
c 19比21小,向下移動
d 19比12大,向前移動
e 19比17大,向前移動
f 找到19了。
僞代碼算法如下
function search(list, searchKey) {
x = list->header;
for (i = list->level; i > 0; i--) {
while (x->forward[i]->key < searchKey) {
x = x->forward[i];
}
}
x = x->forward[1];
if (x->key == searchKey) {
return x->value;
}
return 'not found';
}
- 插入算法
插入17步驟:
a 從最高層即第四層開始
b 17比6大,向前移動
c 17比25小,向下移動
d 17比9大,向前移動
e 17比25小,向下移動
f 17比12大,向前移動
g 17 比 19小,待插入
h 隨機出一個層級,假設2層
i 17的第二層指針爲9的前指針,9的前指針指向17
j 17的第一層指針爲12的前指針,12的前指針指向17
算法僞代碼
function insert(list, searchKey, newValue) {
update[1, ...., maxLevel];
x = list->header;
for (i = list->level; i > 0; i--) {
while (x->forward[i]->key < searchKey) {
x = x->forward[i];
}
update[i] = x;
}
x = x->forward[1];
if (x->key == searchKey && x->value == newValue) {
return 'exists';
}
level = randomLevel();
x = makeNode(level, searchKey, value);
for (i = 1; i < level; i++) {
x->forward[i] = update[i]->forward[i];
update[i]->forward[i] = x;
}
}
- 刪除算法
插入的逆算法,先查找,在刪除,釋放節點
算法僞代碼如下
function delete(list, searchKey) {
update[1, ...., maxLevel];
x = list->header;
for (i = list->level; i > 0; i--) {
while (x->forward[i]->key < searchKey) {
x = x->forward[i];
}
update[i] = x;
}
x = x->forward[1];
if (x->key != searchKey) {
return 'not found';
}
for (i = 1; i < list->level; i++) {
if (update[i]->forward[i] == x) {
update[i]->forward[i] = x->forward[i];
free(x);
}
}
}
- random算法
算法僞代碼
function randomLevel() {
level = 1;
while (random() < p && level < maxLevel) {
level ++;
}
return level;
}