跳錶(skiplist)是在有序鏈表的基礎上進行了擴展,解決了有序鏈表結構查找特定值困難的問題,實現插入、刪除、查找的複雜度均爲O(logN),他是一種可以代替平衡樹的數據結構。LevelDB的核心數據結構是用跳錶實現的,redis的sorted set數據結構也是有跳錶實現的。(參考維基百科:https://en.wikipedia.org/wiki/Skip_list)
其結構如下圖所示:
一、查找
在如下鏈表中查找x
從最上層的鏈(S3)的開頭開始,假設當前位置爲p,它向右指向的節點爲q(p與q不一定相鄰),且q的值爲y。將y與x作比較:
(1) x=y 輸出查詢成功及相關信息
(2) x>y 從p向右移動到q的位置
(3) x<y 從p向下移動一格
如果當前位置在最底層的鏈中(S0),且還要往下移動的話,則輸出查詢失敗。當x=53時候:11<53&&53<max,下移;11<53&&53<30,右移;53<53,命中。
二、插入
首先明確,向跳躍表中插入一個元素,相當於在表中插入一列從S0中某一位置出發向上的連續一段元素。有兩個參數需要確定,即插入列的位置以及它的“高度”。
關於插入的位置,我們先利用跳躍表的查找功能,找到比x小的最大的數y。根據跳躍表中所有鏈均是遞增序列的原則,x必然就插在y的後面。
而插入列的“高度”較前者來說顯得更加重要,也更加難以確定。由於它的不確定性,使得不同的決策可能會導致截然不同的算法效率。爲了使插入數據之後,保持該數據結構進行各種操作均爲O(logn)複雜度的性質,我們引入隨機化算法(Randomized Algorithms)來確定鏈表的高度。
插入元素“40”,且在執行了隨機決策模塊後得到高度爲4
步驟一:找到表中比40小的最大的數,確定插入位置
插入高度爲4的列,並維護跳躍表的結構
三、刪除
刪除操作分爲以下三個步驟:
在跳躍表中查找到這個元素的位置,如果未找到,則退出
將該元素所在整列從表中刪除
將多餘的“空鏈”刪除