演算法筆記 跳表

2021-10-01 09:39:12 字數 1966 閱讀 7192

這種鍊錶加多級索引的結構,就是跳表;

每兩個結點會抽出乙個結點作為上一級索引的結點,那第一級索引的結點個數大約就是 n/2,第二級索引的結點個數大約就是 n/4,第**索引的結點個數大約就是 n/8,依次類推,也就是說,第 k 級索引的結點個數是第 k-1 級索引的結點個數的 1/2,那第 k級索引結點的個數就是 n/(2^k)。

假設索引有 h 級,最高端的索引有 2 個結點。通過上面的公式,我們可以得到 n/(2^h)=2,從而求得 h=log2n-1。如果包含原始鍊錶這一層,整個跳表的高度就是 log2n。我們在跳表中查詢某個資料的時候,如果每一層都要遍歷 m 個結點,那在跳表中查詢乙個資料的時間複雜度就是 o(m*logn)。

每一級索引都最多隻需要遍歷 3 個結點,也就是說 m=3;

m=3的詳細解釋:

假設我們要查詢的資料是 x,在第 k 級索引中,我們遍歷到 y 結點之後,發現 x 大於 y,小於後面的結點 z,所以我們通過 y 的 down 指標,從第 k 級索引下降到第 k-1 級索引。在第 k-1 級索引中,y 和 z 之間只有 3 個結點(包含 y 和 z),所以,我們在 k-1 級索引中最多隻需要遍歷 3 個結點,依次類推,每一級索引都最多隻需要遍歷 3 個結點。

假設原始鍊錶大小為 n,那第一級索引大約有 n/2 個結點,第二級索引大約有 n/4 個結點,以此類推,每上公升一級就減少一半,直到剩下 2 個結點。如果我們把每層索引的結點數寫出來,就是乙個等比數列。

索引的結點總和就是 n/2+n/4+n/8…+8+4+2=n-2。所以,跳表的空間複雜度是 o(n)。也就是說,如果將包含 n 個結點的單鏈表構造成跳表,需要額外再用接近 n 個結點的儲存空間;

在軟體開發中,不必太在意索引占用的額外空間;

在實際的軟體開發中,原始鍊錶中儲存的有可能是很大的物件,而索引結點只需要儲存關鍵值和幾個指標,並不需要儲存物件,所以當物件比索引結點大很多時,那索引占用的額外空間就可以忽略了。

跳表這個動態資料結構,不僅支援查詢操作,還支援動態的插入、刪除操作,而且插入、刪除操作的時間複雜度也是 o(logn)。

當我們不停地往跳表中插入資料時,如果我們不更新索引,就有可能出現某 2 個索引結點之間資料非常多的情況。極端情況下,跳表還會退化成單鏈表。

作為一種動態資料結構,我們需要某種手段來維護索引與原始鍊錶大小之間的平衡,也就是說,如果鍊錶中結點多了,索引結點就相應地增加一些,避免複雜度退化,以及查詢、插入、刪除操作效能下降。

跳表是通過隨機函式來維護前面提到的「平衡性」

其中,插入、刪除、查詢以及迭代輸出有序序列這幾個操作,紅黑樹也可以完成,時間複雜度跟跳表是一樣的。但是,按照區間來查詢資料這個操作,紅黑樹的效率沒有跳表高;

跳表更容易**實現。雖然跳表的實現也不簡單,但比起紅黑樹來說還是好懂、好寫多了,而簡單就意味著可讀性好,不容易出錯。還有,跳表更加靈活,它可以通過改變索引構建策略,有效平衡執行效率和記憶體消耗。

跳表也不能完全替代紅黑樹。因為紅黑樹比跳表的出現要早一些,很多程式語言中的 map 型別都是通過紅黑樹來實現的。做業務開發的時候,直接拿來用就可以了,不用費勁自己去實現乙個紅黑樹,但是跳表並沒有乙個現成的實現,所以在開發中,如果你想使用跳表,必須要自己實現。

跳表使用空間換時間的設計思路,通過構建多級索引來提高查詢的效率,實現了基於鍊錶的「二分查詢」。跳表是一種動態資料結構,支援快速的插入、刪除、查詢操作,時間複雜度都是 o(logn)。跳表的空間複雜度是 o(n)。不過,跳表的實現非常;

跳表的空間複雜度是 o(n)。不過,跳表的實現非常靈活,可以通過改變索引構建策略,有效平衡執行效率和記憶體消耗。雖然跳表的**實現並不簡單,但是作為一種動態資料結構,比起紅黑樹來說,實現要簡單多了。所以很多時候,我們為了**的簡單、易讀,比起紅黑樹,更傾向用跳表。

演算法筆記05 查詢 跳表 雜湊表

二分查詢針對的是乙個有序的資料集合,查詢思想有點類似分治思想。每次都通過跟區間的中間元素對比,將待查詢的區間縮小為之前的一半,直到找到要查詢的元素,或者區間被縮小為 0。二分查詢是一種非常高效的查詢演算法,時間複雜度是 o logn o logn 這種對數時間複雜度,是一種極其高效的時間複雜度,有的...

演算法 跳表資料結構

關於跳表 跳表作為一種特殊的有序單鏈表結構,由於鍊錶本身並不支援二分查詢,而在跳表結構中其通過維護多級索引的方式來實現快速查詢 類似於二分查詢 對於其索引的結構為存在兩個指標,分別是next指標指向同一層級的下乙個節點 同時存在乙個down指標指向下一層相同位置 以及相同資料 的節點 通過增加多級索...

Redis原始碼筆記 跳表

redis 只有在 zset 物件的底層實現用到了跳表,跳表的優勢是能支援平均 o logn 複雜度的節點查詢。zset 物件是唯一乙個同時使用了兩個資料結構來實現的 redis 物件,這兩個資料結構乙個是跳表,乙個是雜湊表。這樣的好處是既能進行高效的範圍查詢,也能進行高效單點查詢。zset 物件能...