資料結構與演算法之美 11 跳表

2021-10-19 23:21:07 字數 1287 閱讀 4505

二分查詢底層依賴的是陣列隨機訪問的特性,所以只能用陣列來實現。如果資料儲存在鍊錶中,還想使用二分查詢,只需要對鍊錶稍加改造,就可以支援類似「二分」的查詢演算法。我們把改造之後的資料結構叫做跳表(skip list)。

對於乙個單鏈表來講,即便鍊錶中儲存的資料是有序的,如果要想在其中查詢某個資料,也只能從頭到尾遍歷鍊錶。這樣查詢效率就會很低,時間複雜度會很高,是 o(n)。

那怎麼來提高查詢效率呢?如果像圖中那樣,對鍊錶建立一級「索引」,查詢起來是不是就會更快一些呢?每兩個結點提取乙個結點到上一級,我們把抽出來的那一級叫做索引或索引層。

這樣如果我們想去尋找某個資料,比如10,可以先在索引層遍歷,找到對應範圍9-13之後,再下降到原屬鍊錶這一層,進行遍歷即可找到。

加來一層索引之後,查詢乙個結點需要遍歷的結點個數減少了,也就是說查詢效率提高了。如果資料量比較大的情況下,可以使用多級索引,在構建索引之後,查詢效率的提公升就會非常明顯。

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

跳表採用的是二分思想,查詢速度會非常快,時間複雜度和二分演算法相同都是o(logn)。

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

因為跳表的原始資料結構是鍊錶,因此不存在插入後資料位移的問題,所以插入的關鍵還是查詢到對應插入的位置。

對於純粹的單鏈表,需要遍歷每個結點,來找到插入的位置。但是對於跳表來說,查詢某個結點的時間複雜度是 o(logn),所以這裡查詢某個資料應該插入的位置,方法是類似的,時間複雜度也是 o(logn)。

刪除和插入類似。

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

跳表的索引是一種動態的資料結構,為了避免複雜度退化及查詢、插入、刪除操作效能下降,需要進行索引的平衡和維護,跳表是通過隨機函式來維護平衡性,這個隨機函式怎麼實現,之後找到參考資料我補充。

資料結構與演算法 跳表

回顧上節 上節課中我們學習了二分法查詢,最基本的二分法查詢需要隨機的訪問資料,底層都是基於陣列的儲存結構 1 思考問題,如果底層是基於鍊錶的方式儲存資料.是否能用二分法查詢呢?我們只要對陣列進行稍微改造,基於鍊錶實現,並在鍊錶的基礎上分別建立對於的索引,就可以快速的基於鍊錶的方式進行查詢,而且該種方...

資料結構與演算法 跳表

二分查詢利用靜態陣列隨機訪問的特性,可以實現在有序的陣列中快速找到某個值,但是因為靜態陣列需要申請連續的記憶體空間,所以當資料規模比較大時,在記憶體中可能無法申請到所需的連續空間。因此,基於這一特性,我們考慮能否將二分查詢應用於鍊錶結構,這樣就避免連續空間的限制,但是對於鍊錶結構,怎樣提高它的查詢效...

資料結構與演算法 跳表

解決鍊錶查詢時耗時過長的問題。英文全稱 skip list 鍊錶 多級索引 鍊錶 跳表 顧名思義,跳表的查詢是在多個鍊錶之間跳躍查詢的,其路線類似於走台階,如下圖所示 舉個栗子 某一時刻,想查詢代號為 8 的節點的資料,按照常規鍊錶查詢,需要從最左側挨個查詢至最右側,遍歷次數為 8 時間複雜度為 o...