數(shù)據(jù)結(jié)構(gòu) - 跳表skiplist

更多數(shù)據(jù)結(jié)構(gòu)內(nèi)容,請參考:數(shù)據(jù)結(jié)構(gòu) - 概要

簡介

疑問中理解技術(shù)

跳表產(chǎn)生的背景
任何技術(shù),都是為了解決特定問題而出現(xiàn)的。

跳表要解決的就是list這種數(shù)據(jù)結(jié)構(gòu)查詢速度過慢的問題。

與list常做對比的數(shù)據(jù)結(jié)構(gòu)是數(shù)組。數(shù)組中元素的查找可以使用二分查找,可以使查找降低到O(logN)的時間復(fù)雜度度

但是對于list來講,查找只能從頭或尾部一個個遍歷,時間復(fù)雜度是O(n)的。

二分查找的效率高,是因?yàn)槊看螌Ρ群螅寄芘懦话氲臄?shù)據(jù),使要搜索的元素集合大大減少。這類似于一種索引技術(shù),而數(shù)組下標(biāo)就是索引。

對于list來講,可以通過額外存儲一些數(shù)據(jù),當(dāng)做list的索引:即在原來list的基礎(chǔ)上,再存儲些數(shù)據(jù),這些數(shù)據(jù)也都是用list存儲的。通過逐層對比這些數(shù)據(jù),實(shí)現(xiàn)縮小搜索范圍的目的。這個在Redis 為什么用跳表而不用平衡樹?中講的比較清楚。

但是跳表并沒有實(shí)現(xiàn)嚴(yán)格的二分。要實(shí)現(xiàn)嚴(yán)格的二分要調(diào)整已經(jīng)存儲的數(shù)據(jù),會增加工作量。

跳表選擇了一種變通做法,通過隨機(jī)函數(shù),決定新插入元素的層高。這種實(shí)現(xiàn)雖然不能保證查詢效率是嚴(yán)格的O(logN),但是平均值和絕大多數(shù)情況下,都能達(dá)到O(logN)的效率。

這是一種折中,但折中折中在沒有降低太多查詢性能的情況下,大大提升了插入效率。這個想法跟紅黑樹的實(shí)現(xiàn)有相似之處。 數(shù)據(jù)結(jié)構(gòu) - 紅黑樹

跳表與平衡樹的比較

跳表會經(jīng)常被用來跟平衡樹,尤其是紅黑樹來比較。

這是因?yàn)樘砗图t黑樹能做的事幾乎相同。

  • 跳表實(shí)現(xiàn)比紅黑樹簡單太多了
  • 跳表的存儲空間比紅黑樹大,但也大不了多少
  • 查詢效率而言,紅黑樹更穩(wěn)定,但絕大多數(shù)情況下區(qū)別不大。
  • 跳表數(shù)據(jù)存放是緊湊的,也就是順序遞增的數(shù)據(jù)是挨著的,這樣就非常適合范圍查找。紅黑樹的范圍查找就不怎么樣了

像redis中sorted set數(shù)據(jù)結(jié)構(gòu)是用跳表來實(shí)現(xiàn)的。而JDK中的TreeMap使用紅黑樹來實(shí)現(xiàn)的。

只能說跳表和紅黑樹各有千秋。個人在選擇其中一個實(shí)現(xiàn)時,需要結(jié)合自己的實(shí)際情況,如能力、時間和需求等。

為啥 redis 使用跳表(skiplist)而不是使用 red-black? 文中討論了redis為何使用的是跳表而非紅黑樹。里面一個共識就是,跳表實(shí)現(xiàn)起來比紅黑樹簡單太多了(redis作者也把這個列為了一個因素),又能滿足需求。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Redis 是一個鍵值對數(shù)據(jù)庫(key-value DB),數(shù)據(jù)庫的值可以是字符串、集合、列表等多種類型的對象,而...
    吳昂_ff2d閱讀 3,727評論 0 5
  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系,并對這種結(jié)構(gòu)定義相應(yīng)的運(yùn)算,而且確保經(jīng)過這...
    Winterfell_Z閱讀 6,584評論 0 13
  • Java繼承關(guān)系初始化順序 父類的靜態(tài)變量-->父類的靜態(tài)代碼塊-->子類的靜態(tài)變量-->子類的靜態(tài)代碼快-->父...
    第六象限閱讀 2,247評論 0 9
  • Redis為什么用跳表而不用平衡樹? 本文是《Redis內(nèi)部數(shù)據(jù)結(jié)構(gòu)詳解》系列的第六篇。在本文中,我們圍繞一個Re...
    meng_philip123閱讀 4,106評論 0 26
  • 賺錢是世界上最實(shí)在的一件事情!而我們喜歡賺取,高品質(zhì)的錢。 何謂高品質(zhì)的錢? 先談,低劣的錢! 低劣的錢,如同吃...
    寧靜的蘭閱讀 369評論 0 0

友情鏈接更多精彩內(nèi)容