跳躍表是一種有序資料結構,他通過每個節點維持多個指向其他節點的指標,從而達到快速訪問的目的。
跳躍表平均支援o(logn),最壞o(n)複雜度的節點查詢,還可以通過順序性來批量處理節點。
redis使用跳躍表作為有序集合鍵的底層實現之一,如果乙個有序集合包含的元素的數量比較多,或者有序集合中元素的成員是比較長的字串時,redis會使用跳躍表來作為有序集合鍵的底層實現。
redis只在兩個地方用到了跳躍表,乙個是實現有序集合鍵,另乙個是在集群節點中作為內部資料結構。
redis跳躍表的實現
redis的跳躍表由redis.h/zskiplistnode和redis.h/zskiplist兩個結構定義,其中zskiplistnode結構用於表示跳躍表節點,而zskiplist結構表示儲存跳躍表節點的相關資訊。圖1表示跳躍表例項:
圖1最左邊是zskiplist結構,該結構包括一下屬性:
header: 指向跳躍表的表頭節點
tail:指向跳躍表的表尾節點
level: 目前跳躍表內,層數最大的哪個節點的層數(表頭節點的層數不計算在內)
length: 記錄跳躍表的長度,即跳躍表目前包含節點的數量
位於zskiplist結構右方的4個zskiplistnode結構,包含一下屬性:
層(level): 節點中用l1,l2,l3標記節點的各個層, l1表示第一層, l2表示第二層, l3表示第三層,以此類推。每個層有兩個屬性:前進指標和跨度。前進指標用於訪問表尾方向的其他節點,而跨度則記錄了前進指標所指向節點和當前節點的距離。在圖1中,連線上帶有數字的箭頭就表示前進指標, 那個數字表示跨度。當程式進行遍歷時,會沿著層的前進指標進行。
後退指標(backward):節點中bw字樣表示標記節點的後退指標,位於當前節點的前乙個節點。後退指標在程式從表尾向表頭遍歷時使用。
分值(score): 各個節點中1.0,2.0, 3.0表示節點所儲存的分值,節點按各自儲存的分值大小從小到大排列。
成員物件(ob): 各個節點的o1, o2, o3表示節點儲存成員物件。
跳躍表節點
跳躍表節點是由redis.h/zskiplistnode結構定義
typeof struct zskiplistnode zskiplistleve;
// 後退指標
struct zskiplistnode *backward;
//分值
double score;
//成員物件
robj *obj;
}zskiplistnode;
1、層
跳躍表的level陣列可以包含多個元素,每個元素包含乙個指向其他節點的指標,程式可以通過層來加快訪問其他節點的速度。一般來說層的數量越多,訪問其他節點的速度越快。下圖2表示高度不同的節點:
2、前進指標
每個層都有乙個指向表尾的前進指標(level[i].forward屬性),用於從表頭向表尾方向訪問節點。遍歷跳躍表中所有節點的路徑, 如下圖3所示:
3、跨度
層的跨度(level[i].span屬性),用於記錄兩個節點的距離。
1)節點的跨度越大,就相距越遠。
2)指向null所有前進指標的跨度都是0
跨度的作用:實際上是用來計算排位(rank)的,在查詢某個節點的過程中,將沿途所訪問層的跨度累計起來,得到的結果就是目標節點在跳躍表的排位。
4、後退指標
節點的後退指標(backward屬性)用於表示表尾向表頭方向訪問節點。可以與一次跳過多個前進節點不同,每個節點只有乙個後退指標,且每次只能後退至前乙個節點。
5、分值和成員
節點的分值(score屬性)是乙個double型別的浮點數,跳躍表中的所有浮點數都是按分值從小到大排列
節點的成員物件(obj屬性)是乙個指標,指向字串物件,而字串物件儲存的是sds值
跳躍表zskiplist的結果定義如下
typeof struct zskiplist zskiplist;
下圖是多個跳躍節點組成的跳躍表
僅靠多個跳躍表節點就乙個組成乙個跳躍表,通過使用乙個zskiplist結構來持有這些節點,程式可以更方便的對整個跳躍表進行處理,如快速訪問表頭節點和表尾節點,快速獲取跳躍表的數量等資訊, 如下圖所示:
Redis學習筆記(四) 跳躍表
跳躍表是一種以o log n 期望時間支援查詢 插入 刪除操作的 有序的資料結構。redis使用跳躍表作為有序集合鍵的底層實現之一。跳表的基本實現原理參考 skip lists a probabilistic alternative to balanced trees redis的跳表由zskipl...
Redis的跳躍表
typedef struct zskiplistnode level 層 層高1 32隨機,一般層數量越多,訪問其他節點速度越快 struct zskiplistnode backward 後退指標 只能退至前乙個節點 double score 分值 所有節點按分值從小到大排序 robj obj 成...
四 跳躍表(Redis)
跳躍表 skiplist 是一種有序資料結構,它通過在每個節點中維持多個指向其他節點的 指標,從而達到快速訪問節點的目的。redis 的跳躍表由 redis.h zskiplistnode 和 redis.h zskiplist 兩個結構定 義,其中zskiplistnode結構用於表示跳躍表節點,...