回顧上節:上節課中我們學習了二分法查詢,最基本的二分法查詢需要隨機的訪問資料,底層都是基於陣列的儲存結構
1>思考問題,如果底層是基於鍊錶的方式儲存資料.是否能用二分法查詢呢?
我們只要對陣列進行稍微改造,基於鍊錶實現,並在鍊錶的基礎上分別建立對於的索引,就可以快速的基於鍊錶的方式進行查詢,而且該種方式支援隨機的插入,刪除操作,redis就是基於這種資料結構來存放有序的資料集合的.
2>如何理解跳表這種資料結構
至於鍊錶的資料結構,我們為查詢乙個元素,需要遍歷這張表,直到找到對應的資料即可,這樣需要遍歷整張表的時間複雜度是o(n);效率仍然還是很高,
我們可以在基於鍊錶的基礎上,每隔2個節點去建立乙個索引層,使用該索引層可以很快的找到對應的資料,其中down指標指向下一節節點.
說明:比如我們需要查詢的資料是16,我們首先會去遍歷第一級索引,當遍歷到13的時候,後面的資料是17,16在13和17之間,我們在13這一資料down到下一級,從下一級的13向後遍歷1個資料就可以找到我們需要的資料16,這樣的查詢效能有個較大的提公升.加上這樣的索引層之後,相比遍歷整張鍊錶,需要遍歷的資料減少.在效率上提公升.
3>可以建立多級索引來實現遍歷的效率
在上圖的基礎上,我們可以在第一級索引上每隔2個資料繼續建立索引,叫第2級索引.,這要查詢的話需要遍歷的資料更加少了
總結:這種鍊錶+索引的結構就叫做跳表,他比鍊錶需要更多的儲存空間,來存放索引結構,但是在查詢效率上有大的提公升,用到的思想還是空間來換取時間.根據調表的查詢效率的時間複雜度是o(logn)
4>跳表支援高效的動態插入和刪除,時間複雜度是o(logn)
在單鏈表中,隨機的插入刪除的時間複雜度是o(1),,但是只要保證鍊錶的有序性,單鏈表的插入和刪除的時間複雜度也會變為o(n),但是基於這種跳表的結構就不會,在插入的時候,更跳表的查詢思路是一樣的,所以時間複雜度為o(logn)
現在來看看跳表的刪除:如果刪除的資料在原始鍊錶中,刪除即可,如果同時在索引和原始鍊錶中,我們既要刪除原始鍊錶的資料又要刪除索引中的資料,.
總結:跳表的插入過程:遍歷第3級索引:6在1和13之間,down到第2級索引,遍歷第2級索引,6在1和7之間,down到第一級索引,遍歷第一級索引,6在4和7之間,從4 down到原始鍊錶進行遍歷,將6插入到相應的位置.
4>跳表結構帶來的弊端
當我們很頻繁的往跳表中增加刪除元素,我們會發現,2個索引之間的資料過多,容易退化成單鏈表
基於這種情況,
我們會生成乙個隨機數字 k,決定這個資料在原始鍊錶中存在,且在第k級索引中建立該資料的索引,這樣能大大的避免2節點之間的資料過多而退化成單鏈表的資料結構
這節課的總結:基於有序鍊錶我們也能實現快速的查詢操作,且可以支援頻繁的插入刪除操作,這種資料結構是跳表,查詢,刪除,增加的時間複雜度是o(logn),它是一種動態的資料結構.
資料結構與演算法 跳表
二分查詢利用靜態陣列隨機訪問的特性,可以實現在有序的陣列中快速找到某個值,但是因為靜態陣列需要申請連續的記憶體空間,所以當資料規模比較大時,在記憶體中可能無法申請到所需的連續空間。因此,基於這一特性,我們考慮能否將二分查詢應用於鍊錶結構,這樣就避免連續空間的限制,但是對於鍊錶結構,怎樣提高它的查詢效...
資料結構與演算法 跳表
解決鍊錶查詢時耗時過長的問題。英文全稱 skip list 鍊錶 多級索引 鍊錶 跳表 顧名思義,跳表的查詢是在多個鍊錶之間跳躍查詢的,其路線類似於走台階,如下圖所示 舉個栗子 某一時刻,想查詢代號為 8 的節點的資料,按照常規鍊錶查詢,需要從最左側挨個查詢至最右側,遍歷次數為 8 時間複雜度為 o...
演算法 跳表資料結構
關於跳表 跳表作為一種特殊的有序單鏈表結構,由於鍊錶本身並不支援二分查詢,而在跳表結構中其通過維護多級索引的方式來實現快速查詢 類似於二分查詢 對於其索引的結構為存在兩個指標,分別是next指標指向同一層級的下乙個節點 同時存在乙個down指標指向下一層相同位置 以及相同資料 的節點 通過增加多級索...