跳躍表(維基百科):
html
從圖中能夠看到, 跳躍表主要由如下部分構成:redis
表頭(head):負責維護跳躍表的節點指針。算法
跳躍表節點:保存着元素值,以及多個層。數據結構
層:保存着指向其餘元素的指針。高層的指針越過的元素數量大於等於低層的指針,爲了提升查找的效率,程序老是從高層先開始訪問,而後隨着元素值範圍的縮小,慢慢下降層次。ide
表尾:所有由 svg
容許重複的 member 的 score 值,還要檢查 score 值能夠重複時,單靠 member 域都一併檢查才行。函數
每一個節點都帶有一個高度爲 1 層的後退指針,用於從表尾方向向表頭方向迭代:當執行 ZREVRANGEBYSCORE 這類以逆序處理有序集的命令時,就會用到這個屬性。this
這個修改版的跳躍表由 redis.h/zskiplistNode 定義:
spa
typedef struct zskiplistNode {
// member 對象
robj *obj;
// 分值
double score;
// 後退指針
struct zskiplistNode *backward;
// 層
struct zskiplistLevel {
// 前進指針
struct zskiplistNode *forward;
// 這個層跨越的節點數量
unsigned int span;
} level[];
} zskiplistNode;指針
如下是操做這兩個數據結構的 API ,它們的做用以及相應的算法複雜度:
函數 | 做用 | 複雜度 | |
---|---|---|---|
zslFreeNode | 釋放給定的跳躍表節點 | 最壞 O(1) | |
zslFree | 釋放給定的跳躍表 | 最壞 O(N) | |
score 和 zslDeleteNode | 刪除給定的跳躍表節點 | 最壞 O(N) | |
member 和 zslFirstInRange | 找到跳躍表中第一個符合給定範圍的元素 | 最壞 O(N) 平均 O(logN) | |
zslDeleteRangeByScore | 刪除 zslDeleteRangeByRank | 刪除給定排序範圍內的全部節點 | 最壞 O(N2) |
zslGetElementByRank | 根據給定排位,返回該排位上的元素節點 | 最壞 O(N) 平均 O(logN) |
和字典、鏈表或者字符串這幾種在 Redis 中大量使用的數據結構不一樣, 跳躍表在 Redis 的惟一做用, 就是實現有序集數據類型。
跳躍表將指向有序集的 member 域的指針做爲元素, 並以 x 、 z 三個 6 、 15 分別建立三個 member 和 member 和 member 和 有序集》章節。
跳躍表是一種隨機化數據結構,它的查找、添加、刪除操做均可以在對數指望時間下完成。
跳躍表目前在 Redis 的惟一做用就是做爲有序集類型的底層數據結構(之一,另外一個構成有序集的結構是字典)。
爲了適應自身的需求,Redis 基於 William Pugh 論文中描述的跳躍表進行了修改,包括:
score 和 <tt literal"="" style="background-color: transparent; color: rgb(34, 34, 34); font-size: 1.1em;">memeber 。
每一個節點帶有高度爲 1 層的後退指針,用於從表尾方向向表頭方向迭代。