【redis內部結構】skiplist

skiplist 是組成有序集合(sort set)的重要數據結構

1. skiplist 圖示介紹

a. 單鏈表
這裏寫圖片描述
b. 第二層中,第一層中每兩個元素,提取出一個元素。(可以跳躍個n2 個節點)
這裏寫圖片描述
c. 第三層中,以第二層爲基礎,第二層中每兩個元素,提取出一個元素。(可以跳躍n2+n4 個節點)
這裏寫圖片描述
d.第四層中,以第三層爲基礎,第三層中每兩個元素,提取出一個元素。
(可以跳躍n2+n4+n8 個節點)
這裏寫圖片描述
e.最終一層層向上,每層的元素數量遞減,等比數列。類似於平衡樹結構。

具體元素組成的跳躍表
這裏寫圖片描述

這樣標準的跳躍鏈表:其不難得出時間複雜度爲(O)logn
但是維護這樣標準的跳躍表(上一層元素的數量是當前層元素數量的12 )。增刪改是不切實際的。

因此採用隨機法來生成層級,每一個新的元素的層級都是隨機出來的。
最終生成的跳躍表可能如下圖所示:
這裏寫圖片描述
每一層都可以看成是單鏈表,第一層包含所有的元素。

- 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章