跳表(skiplist )是乙個特殊的鍊錶,相比一般的鍊錶,有更高的查詢效率,可比擬二叉查詢樹,
平均期望的查詢、插入、刪除時間複雜度都是o(log n),許多知名的開源軟體(庫)中的資料
結構均採用了跳表這種資料結構∶
我們拿我們以前的有序鍊錶相比:
我們可以很清楚的看出,有序鍊錶的查詢比較慢,時間複雜度為o(n),它的刪除和插入操作比較快,我們怎樣才能讓它的查詢的時間複雜度也變快呢?
能不能將我們的鍊錶實現二分的查詢,也就是longn,答案是肯定的,也就是我們下面所說的這種跳表。
跳表的查詢和我之前做過的一道題特別類似,二維陣列的查詢
假設我們查詢31這個數字
整個查詢過程如下所示
對於插入來說,我們比如要插入乙個21的數值
對於刪除來說,我們比如要插入乙個17的數值
我們知道單鏈表查詢的時間複雜度為o(n),而插入、刪除操作需要先找到對應的位置,所以插入、刪除的時間複雜度也是o(n)。
那麼,跳表的時間複雜度是多少呢?
如果按照標準的跳表來看的話,每一級索引減少k/2個元素(k為其下面一級索引的個數),那麼整個跳表的高度就是(log n)。
學習過平衡二叉樹的同學都知道,它的時間複雜度與樹的高度成正比,即o(log n)。
所以,這裡跳表的時間複雜度也是o(log n)。(這裡不一步步推倒了,只要記住,查詢時每次減少一半的元素的時間複雜度都是o(log n),比如二叉樹的查詢、二分法查詢、歸併排序、快速排序)
我們還是以標準的跳表來分析,每兩個元素向上提取乙個元素,那麼,最後額外需要的空間就是:
n/2 + (n/2)^2 + (n/2)^3 + … + 8 + 4 + 2 = n - 2
所以,跳表的空間複雜度是o(n)。
前四項紅黑樹都可以完成,且時間複雜度與跳表一致
但是,最後一項,紅黑樹就不如跳表查詢的快
在跳表中,要查詢區間的元素,我們只要定位到兩個區間端點在最低層級的位置,然後按順序遍歷元素就可以了,非常高效。
而紅黑樹只能定位到端點後,再從首位置開始每次都要查詢後繼節點,相對來說是比較耗時的。
跳表實現起來很容易且易讀,紅黑樹實現起來相對困難,所以redis選擇使用跳表來實現有序集合。
redis面試題,求求你別再問我redis了
室友有個大佬,一說redis就問我為什麼使用redis,redis單執行緒為什麼這麼快,redis redis的部分面試題,自己整理的,當然實際工作中使用的redis比較簡單,但是了解redis部分底層還是有必要的 什麼是redis redis 是乙個使用 c 語言寫成的,開源的基於記憶體的,單執行...
redis面試題,求求你別再問我redis了
室友有個大佬,一說redis就問我為什麼使用redis,redis單執行緒為什麼這麼快,redis redis的部分面試題,自己整理的,當然實際工作中使用的redis比較簡單,但是了解redis部分底層還是有必要的 什麼是redis redis 是乙個使用 c 語言寫成的,開源的基於記憶體的,單執行...
拜託,面試別再問我跳表了!
跳表是乙個隨機化的資料結構,實質就是一種可以進行二分查詢的有序鍊錶。跳表在原有的有序鍊錶上面增加了多級索引,通過索引來實現快速查詢。跳表不僅能提高搜尋效能,同時也可以提高插入和刪除操作的效能。考慮乙個有序鍊錶,我們要查詢3 7 17這幾個元素,我們只能從頭開始遍歷鍊錶,直到查詢到元素為止。上述這個鍊...