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