跳錶:一種平衡樹的機率性替代品

來源:互聯網
上載者:User

跳錶是一種可以替代平衡樹的資料結構。跳錶追求的是機率性平衡,而不是嚴格平衡。因此,跟平衡二叉樹相比,跳錶的插入刪除操作要簡單得多,執行也更快。

二叉樹可以用來實現字典和有序表等抽象資料結構。在元素隨機插入的情境,二叉樹可以很好應對。然而,在有序插入的情況下,二叉樹就退化了(鏈表),效能非常差。如果有辦法對待插入元素進行隨機排列,二叉樹大機率可以運行良好。大部分情況下,插入是線上進行的,因此隨機排列並不具有可行性。平衡樹在操作時對樹結構進行調整以滿足平衡條件,因此獲得理想效能。

跳錶是一種機率性可行的平衡二叉樹替代資料結構。跳錶通過一個隨機數產生器實現平衡。雖然跳錶最壞情況下(worst-case)效能也很差,但是沒有任何輸入序列必然會導致最壞情況發生(這點類似劃分元素(pivot point)隨機選定的快排)。跳錶極度不平衡發生的機率非常低(一個包含250個元素的字典,一次尋找需要花3倍期望時間的機率小於百萬分之一)。跳錶平衡機率跟隨機插入的二叉樹差不多,好處是插入順序不要求隨機。

實現機率性平衡比嚴格控制平衡要簡單得多。對很多應用來說,跳錶用起來比平衡樹更自然,而且演算法更簡單。跳錶演算法簡單性意味著更容易實現,而且與平衡樹和自適應樹相比有常數倍數的效能提升。跳錶在空間上也比較高效。平均每個元素只需要額外耗費個2指標(甚至可以配置得更低),並不需要在每個節點上都存與平衡和優先順序相關的資料。 結構

搜尋一個鏈表時,我們需要遍曆每個節點(如圖 1a)。如果列表是有序的,偶數節點另存一個指向下一個偶數節點的指標(如圖 1b),我們只需要檢查最多(n/2)+1個節點(n是鏈表規模)。如果序號為4的倍數的節點都有一個往前跳4步的節點,那麼最多隻需要檢查(n/4)+2次。如果,序號為2^i的節點有一個向前跳2^i步的指標,那麼則需要檢查log2 n次了。這種資料結構可以用來做快速搜尋,但是插入和刪除並沒有可行性。

有k個前進指標的節點成為k層節點。如果第2^i個節點有一個向前跳2^i步的指標,那麼每層節點數滿足以下關係:第1層有50%的節點;第2層有25%的節點;第3層有12.5%的節點;以此類推。假設每層的比例還是一樣,但是節點隨機播放,會怎樣呢(圖 1e)。節點第i個前進指標不嚴格跳2^i步,而是可以跳任意步。由於不需要維持特殊條件,插入節點層數隨機產生,插入和刪除只需要做局部修改。極端情況下,有些層次分布會導致極差的效能,不過接下來我們會看到這種情況非常罕見。這種資料結構在鏈表的基礎上加上額外指標以跳過一些中間節點,因此命名為跳錶演算法

這小節介紹用於搜尋插入刪除的演算法。搜尋操作返回與給定鍵(key)關聯的值(value),鍵不存在時則失敗。插入操作將給定鍵關聯到新的值,如果鍵不存在則插入新的節點。刪除操作刪除給定鍵。另外,類似最小鍵下一鍵這類操作實現起來也非常簡單。

每個元素由一個節點表示,層次由節點在插入時隨機選定,與已有元素無關。層次為i的節點擁有i個前進指標,下標分別是1至i。節點不需要儲存層數。選定一個合適的常量MaxLevel,層數在這個範圍內。跳錶的層數時當前所有節點層數的最大值,或者當跳錶為空白是,層數為1。用一個頭向量儲存從層次1到MaxLevel的向前指標。指標高於當前跳錶層數的部分直接指向NIL。 初始化

約定NIL元素,其鍵比所有合法建都大(上限)。跳錶的任意層都以NIL結尾。新的跳錶初始化成層數只有1,並且所有表頭所有前進指標都指向NIL。 尋找

尋找某個元素時,需要逐層遍曆所有鍵不超過給定鍵的節點。如果當前層前進節點已經不符合條件了,往下一層開始遍曆。當遍曆進行到第1層時,下一個節點就是目標節點(如存在)。

Search(list, searchKey)    x := list->header    for i := list->level downto 1 do        while x->forward[i]->key < searchKey do            x = x->forward[i]    x := x->forward[1]    if x->key = searchKey    then        return x->value    else        return failure
插入/刪除

插入或者刪除節點,只需先執行搜尋操作(圖 3),然後視情況重新拼接。虛擬碼如下所示:

Insert(list, searchKey, newValue)    local update[1..MaxLevel]    x := list-header    for i := list->level downto 1 do        while x->forward[i]->key < searchKey do            x := x->forward[i]        update[i] := x    x := x->forward[i]    if x->key = searchKey then        x->value := newValue    else        lvl := randomLevel()        if lvl > list->level then            for i := list->level+1 to lvl do                update[i] := list->header            list->level = lvl        x := makeNode(lvl, searchKey, value)        for i := 1 to lvl do            x->forward[i] = update[i]->forward[i]            update[i]->forward[i] := x

圖3展示了搜尋過程。注意到,搜尋的過程中維護了一個名為update的向量,在每次降層搜尋時更新。搜尋完成後,update剛好記錄了各層在操作位置(圖中環)左邊最近的節點:

元素 節點
update[1] 12
update[2] 9
update[3] 6
update[4] 6

如果插入時產生了一個比當前最大層更大的層數,則需要更新跳錶層數並且初始化update向量對應部分。

接下來,看看刪除操作的虛擬碼:

Delete(list, searchKey)    local update[1..MaxLevel]    x := list-header    for i := list->level downto 1 do        while x->forward[i]->key < searchKey do            x := x->forward[i]        update[i] := x    x := x->forward[i]    if x->key < searchKey then        for i := 1 to list->level do            if update[i]->forward[i] != x then break            update[i]->forward[i] = x->forward[i]        free(x)        while list->level > 1 and list->header->forward[list->level] = NIL do            list->level := list->level - 1

在每次刪除時,需要檢查被刪除節點是否是最大層節點。如果是,需要對跳錶層數做對應調整。 隨機函數

接下來,需啊確定一個隨機數產生函數,其機率分布使得第i層中有50%的節點同時資料第i+1層。先拋開具體數值,我們在討論一個分數p,對於有i層指標的節點中p部分,同時擁有i+1層指標。以下便是一個非常理想的隨機數產生函數,隨機層數產生與跳錶元素及規模無關:

randomLevel()    lvl := 1    while random() < p and lvl < MaxLevel do        lvl := lvl + 1    return lvl

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.