1. 程式人生 > >Redis系列(十二):資料結構SortedSet跳躍表中基本操作命令和原始碼解析

Redis系列(十二):資料結構SortedSet跳躍表中基本操作命令和原始碼解析

1.SkipList

Redis的sortedSet資料結構是有序不重複的(索引為唯一的,資料(score)卻可以重複),

跳錶是redis的一個核心元件,也同時被廣泛地運用到了各種快取地實現當中,它的主要優點,

就是可以跟紅黑樹、AVL等平衡樹一樣,做到比較穩定地插入、查詢與刪除。理論插入查詢刪除的演算法時間複雜度為O(logN)。

 

 2.什麼是跳錶

連結串列,相信大家都不陌生,維護一個有序的連結串列是一件非常簡單的事情,我們都知道,在一個有序的連結串列裡面,查詢跟插入的演算法複雜度都是O(n)。

我們能不能進行優化呢,比如我們一次比較兩個呢?那樣不就可以把時間縮小一半?同理,如果我們4個4個比,那不就更快了?

跳錶就是這樣的一種資料結構,結點是跳過一部分的,從而加快了查詢的速度。跳錶跟紅黑樹又有什麼差別呢?

既然兩者的演算法複雜度差不多,

 

 

為什麼Redis要使用跳錶而不使用紅黑樹呢?

跳錶相對於紅黑樹,主要有這幾個優點:1.程式碼相對簡單,手寫個跳錶還有可能,

手寫個紅黑樹試試?2.如果我們要查詢一個區間裡面的值,用平衡樹可能會麻煩。這裡的麻煩指的是實現和理解上,

平衡二叉樹查詢一段區間也是可以做到的。3.刪除一段區間,這個如果是平衡二叉樹,就會相當困難,畢竟設計到樹的平衡問題,而跳錶則沒有這種煩惱。

好了,相信你對跳錶已經有一些認識了,我們來簡單介紹平衡二叉樹的幾個基本操作。

2.原始碼分析

#include<stdio.h>

#include<stdlib.h>

 

#define ZSKIPLIST_MAXLEVEL 32

#define ZSKIPLIST_P 0.25

#include <math.h>

 

//跳錶節點

typedef struct zskiplistNode {

    int key;

    int value;

    struct zskiplistLevel {

        struct zskiplistNode *forward;

    } level[1];

} zskiplistNode;

 

//跳錶

typedef struct zskiplist {

    struct zskiplistNode *header;

    int level;

} zskiplist;

&n