跳錶的資料結構
阿新 • • 發佈:2021-08-31
調錶的核心思想
跳錶的核心思想是“剪枝”,具體是如下方式實現
如果是一個簡單的連結串列,那麼我們知道在連結串列中查詢一個元素I的話,需要將整個連結串列遍歷一次。
如果是說連結串列是排序的,並且節點中還儲存了“跳躍”的指向後續節點的指標的話,那麼在查詢一個節點時,僅僅需要遍歷N/2個節點即可。
從上圖中已經可以看到"層"的出現使得時間複雜度降為原來的一半。
一次典型的調錶查詢
skiplist上的查詢路徑展示
skiplist正是受這種多層連結串列的想法的啟發而設計出來的。實際上,按照上面生成連結串列的方式,上面每一層連結串列的節點個數,是下面一層的節點個數的1/P(redis中P為0.25),這樣查詢過程就非常類似於一個二分查詢,使得查詢的時間複雜度可以降低到O(log n)。
核心資料結構
#define ZSKIPLIST_MAXLEVEL 32 //最大層數 #define ZSKIPLIST_P 0.25 //P typedef struct zskiplistNode { robj *obj; double score; struct zskiplistNode *backward; //後向指標 struct zskiplistLevel { struct zskiplistNode *forward;//每一層中的前向指標 unsigned int span;//x.level[i].span 表示節點x在第i層到其下一個節點需跳過的節點數。注:兩個相鄰節點span為1 } level[]; } zskiplistNode; typedef struct zskiplist { struct zskiplistNode *header, *tail; unsigned long length;//節點總數 int level;//總層數 } zskiplis