跳躍表 在每個節點維持多個指向其他節點的指標,達到快速訪問節點的目的。redis使用跳躍表作為有序集合鍵的底層實現之一。
zskiplist結構:
zskiplistnode結構:
5.1.1 跳躍表節點
type struct1. 層跳表節點的level陣列包含多個元素,每個元素代表一層。層數大小在1~32之間隨機生成。zskiplistnode level;
}zskiplistnode;
2. 前進指標
通過每層的前進指標(level[i].forward)遍歷整個調整的節點,直到遇到null。
3. 跨度
層的跨度(level[i].span)記錄了該層指向的下乙個節點的距離。指向null的層的跨度為0。在遍歷的過程,記錄訪問路徑上每個層數的跨度,當到達目的節點時,累加得到的跨度就是目的節點在跳躍表中的排位。
4. 後退指標
每個節點只有乙個後退節點
5. 分值和成員
節點的分值(score屬性)是乙個double型別的浮點數,節點按照各自的分值從小到大排列
節點的成員物件(obj屬性)是乙個指標,它指向乙個字串物件,而字串物件存放著乙個sds值
節點的分值可以相同,但成員物件必須唯一。當分值相同時,根據儲存的字串物件在字典中的順序排序。
5.1.2 跳躍表
zskiplist是為了更方便的操作跳躍表,其中包含了可以訪問跳表表頭和跳表表尾的指標,或是快速獲取跳表節點的數量。
查詢時間複雜度為o(logn),根紅黑樹一致。區別是紅黑樹維護平衡需要旋轉,操作複雜,而跳表設計簡單,但需要更多的儲存空間。
5.3.1 插入流程
新節點從最高層開始逐層向下比較尋找,確定插入位置,複雜度o(logn)
將索引插入到原鍊錶,複雜度o(1)
利用拋硬幣的隨機方式,決定新節點是否提公升到上一級索引。若為正,新節點層數加一,並繼續嘗試,直到為負。時間複雜度為o(logn),但是redis中限制了層數最多32,應該是o(1)
假設節點每層節點數是上一層的k倍,那麼總節點數計算如下公式。比如當k為2時,總結點數為2n。這也說明了跳躍表,是一種用空間換時間的設計思路,相對於紅黑樹來說,操作簡單,但需要的儲存空間更多。
5.3.2 刪除流程
從最高層向下比較尋找,找到節點後,刪除節點,刪除節點每層的時候,需要將前節點的當前層指標指向後節點的當前層,即注意維護層之間的指標關係。
參考:關於跳躍表的一點理解
第五章 跳躍表
跳躍表 skiplist 是一種有序資料結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。支援平均o logn 最壞o n 複雜度的節點查詢,還可以通過順序性操作來批量處理節點。redis只在兩個地方用到了跳躍表,乙個是實現有序集合鍵,另乙個是在集群節點中用作內部資料結...
《Redis設計與實現》第五章 跳躍表
跳表是一種有序的資料結構,它通過在每個節中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。跳躍表支援平均 logn 最壞o n 時間複雜度的查詢。跳躍表作為有序集合鍵的底層實現之一。redis兩個地方用到了跳躍表 乙個是實現有序集合鍵 另外乙個是在集群節點中用作內部資料結構,除此之外沒有其他...
Redis設計與實現 筆記 第五章 跳躍表
跳躍表是一種有序的資料結構,通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的.跳躍表支援平均 o logn 最壞 o n 的複雜度節點查詢,還可以通過順序性操作批量節點.節點整體效率接近紅黑樹,且 複雜度低於紅黑樹.跳表的實現思路也類似於紅黑樹,區別於紅黑樹通過大於小於等於某乙...