1. 程式人生 > >【從下而上學習Redis】資料結構篇(一):跳躍表(skiplist)

【從下而上學習Redis】資料結構篇(一):跳躍表(skiplist)

描述

跳躍表(skiplist)是對有序的連結串列增加上附加的前進連結,在列表中的查詢可以快速的跳過部分列表,因此取名跳躍表。跳躍表大概就長得如下圖所示
再舉個形象點的栗子,就像我們如果要去國外,如果徒步去當然會累死,於是我們先坐飛機,下飛機後乘坐汽車,然後再走一段路最終到達目的地,於是我可以得到一張這樣子的跳躍表:

其實說白了,無非就是一種加了索引的有序連結串列。而與有序連結串列最大的區別,就是跳躍表增刪查改的平均效率都是O(logN),在大部分情況下,跳躍表的效率可以和平衡樹相媲美甚至更快,而實現比平衡樹來的更為簡單,當然更吃一些空間。如今有不少程式使用跳躍表來代替平衡樹。 redis使用跳躍表作為有序集合鍵的底層實現之一。

原始碼解析

Redis的跳躍表實現由zskiplist和zskiplistNode兩個結構組成,其中zskiplist用於儲存跳躍表資訊,zskiplistNode用於表示跳躍表結點
/* ZSETs use a specialized version of Skiplists */
/*
 * 跳躍表節點
 */
typedef struct zskiplistNode {

    // 成員物件
    robj *obj;
    // 分值
    double score;
    // 後退指標
    struct zskiplistNode *backward;
    // 層
    struct zskiplistLevel {
        // 前進指標
        struct zskiplistNode *forward;
        // 跨度
        unsigned int span;
    } level[];

} zskiplistNode;

/*
 * 跳躍表
 */
typedef struct zskiplist {

    // 表頭節點和表尾節點
    struct zskiplistNode *header, *tail;
    // 表中節點的數量
    unsigned long length;
    // 表中層數最大的節點的層數
    int level;

} zskiplist;
程式碼來自huangz註釋的redis原始碼,地址在這裡https://github.com/huangz1990/redis-3.0-annotated

(跳躍表建立索引的方法等挖坑代填)