跳躍表原理和實現

2022-07-04 04:12:14 字數 1264 閱讀 7375

有時候會被問到鍊錶如果做到二分搜尋,可能會有部分的人會去把鍊錶中的值儲存到陣列來進行二分,但是如果知道跳躍表的話,那麼這個資料結構就可以解決這個困惑,它允許快速查詢乙個有序連續元素的資料鏈表,它的效率可以做到和二分相同,都是o(logn)的平均時間複雜度,其空間複雜度為o(n)。

跳躍列表是在很多應用中有可能替代平衡樹而作為實現方法的一種資料結構。跳躍列表的演算法有同平衡樹一樣的漸進的預期時間邊界,並且更簡單、更快速和使用更少的空間。----by 發明者

像是redis中有序集合就使用到了跳躍表。

首先,應該要了解跳躍表的性質;

由很多層結構組成;

每一層都是乙個有序的鍊錶,排列順序為由高層到底層,都至少包含兩個鍊錶節點,分別是前面的head節點和後面的nil節點;

最底層的鍊錶包含了所有的元素;

如果乙個元素出現在某一層的鍊錶中,那麼在該層之下的鍊錶也全都會出現(上一層的元素是當前層的元素的子集);

鍊錶中的每個節點都包含兩個指標,乙個指向同一層的下乙個鍊錶節點,另乙個指向下一層的同乙個鍊錶節點;

可以看到,這裡一共有4層,最上面就是最高層(level 3),最下面的層就是最底層(level 0),然後每一列中的鍊錶節點中的值都是相同的,用指標來連線著。跳躍表的層數跟結構中最高節點的高度相同。理想情況下,跳躍表結構中第一層中存在所有的節點,第二層只有一半的節點,而且是均勻間隔,第三層則存在1/4的節點,並且是均勻間隔的,以此類推,這樣理想的層數就是logn。

其基本原理就是從最高層的鍊錶節點開始,如果比當前節點要大和比當前層的下乙個節點要小,那麼則往下找,也就是和當前層的下一層的節點的下乙個節點進行比較,以此類推,一直找到最底層的最後乙個節點,如果找到則返回,反之則返回空。

**實現大致為:

find(x)   

}

既然要插入,首先需要確定插入的層數,這裡有不一樣的方法。1. 看到一些部落格寫的是拋硬幣,只要是正面就累加,直到遇見反面才停止,最後記錄正面的次數並將其作為要新增新元素的層;2. 還有就是一些部落格裡面寫的統計概率,先給定乙個概率p,產生乙個0到1之間的隨機數,如果這個隨機數小於p,則將高度加1,直到產生的隨機數大於概率p才停止,根據給出的結論,當概率為1/2或者是1/4的時候,整體的效能會比較好(其實當p為1/2的時候,也就是拋硬幣的方法)。

當確定好要插入的層數以後,則需要將元素都插入到從最底層到第k層。

在各個層中找到包含指定值的節點,然後將節點從鍊錶中刪除即可,如果刪除以後只剩下頭尾兩個節點,則刪除這一層。

用Python深入理解跳躍表原理及實現

最近看 redis 的實現原理,其中講到 redis 中的有序資料結構是通過跳躍表來進行實現的。第一次聽說跳躍表的概念,感到比較新奇,所以查了不少資料。其中,網上有部分文章是按照如下方式描述跳躍表的 這種描述便於理解,很容易讓人理解到跳躍表是建立了類似索引的東西,從而提高效率的。但是,這樣描述給人的...

Redis的跳躍表底層實現

跳躍表是一種有序的資料結構,主要用在zset 有序集合 和集群節點的內部資料結構。在大部分情況下,跳躍表的效率可以和平衡樹相媲美,並且因為跳躍表的實現比平衡樹要來得更為簡單,所以有不少程式都使用跳躍表來代替平衡樹。注意mysql的底層採用的是b 樹實現。跳躍表的實現 redis的跳躍表由redis....

儲存系統實現 跳躍表實現索引檢索

這一篇是我所實現的乙個通過跳躍表的方式進行索引的檢索。跳躍表的基本思路把單步檢索擴充套件到多步檢索,這樣依賴減少檢索的步驟來公升效能。先用一張流程圖來闡述我檢索的步驟。讀索引整體流程圖 這裡舉乙個具體的例子來說一下檢索的步驟。這裡說一種檢索到的情況,假設整個檔案表10萬條,id是連續自增,檢索id ...