SkipList 跳錶

來源:互聯網
上載者:User

標籤:style   blog   http   使用   strong   width   

為什麼選擇跳錶

目前經常使用的平衡資料結構有:B樹,紅/黑樹狀結構,AVL樹,Splay Tree, Treep等。

 

想象一下,給你一張草稿紙,一隻筆,一個編輯器,你能立即實現一顆紅/黑樹狀結構,或者AVL樹

出來嗎? 很難吧,這需要時間,要考慮很多細節,要參考一堆演算法與資料結構之類的樹,

還要參考網上的代碼,相當麻煩。

 

用跳錶吧,跳錶是一種隨機化的資料結構,目前開源軟體 Redis 和 LevelDB 都有用到它,

它的效率和紅/黑樹狀結構以及 AVL 樹不相上下,但跳錶的原理相當簡單,只要你能熟練操作鏈結表,

就能輕鬆實現一個 SkipList。

 

有序表的搜尋

考慮一個有序表:


 

從該有序表中搜尋元素 < 23, 43, 59 > ,需要比較的次數分別為 < 2, 4, 6 >,總共比較的次數

為 2 + 4 + 6 = 12 次。有沒有最佳化的演算法嗎?  鏈表是有序的,但不能使用二分尋找。類似二叉

搜尋樹,我們把一些節點提取出來,作為索引。得到如下結構:



 這裡我們把 < 14, 34, 50, 72 > 提取出來作為一級索引,這樣搜尋的時候就可以減少比較次數了。

 我們還可以再從一級索引提取一些元素出來,作為二級索引,變成如下結構:

 

  

 

     這裡元素不多,體現不出優勢,如果元素足夠多,這種索引結構就能體現出優勢來了。

 

跳錶

下面的結構是就是跳錶:

 其中 -1 表示 INT_MIN, 鏈表的最小值,1 表示 INT_MAX,鏈表的最大值。

 

 

跳錶具有如下性質:

(1) 由很多層結構組成

(2) 每一層都是一個有序的鏈表

(3) 最底層(Level 1)的鏈表包含所有元素

(4) 如果一個元素出現在 Level i 的鏈表中,則它在 Level i 之下的鏈表也都會出現。

(5) 每個節點包含兩個指標,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素。

 

跳錶的搜尋


 

例子:尋找元素 117

(1) 比較 21, 比 21 大,往後面找

(2) 比較 37,   比 37大,比鏈表最大值小,從 37 的下面一層開始找

(3) 比較 71,  比 71 大,比鏈表最大值小,從 71 的下面一層開始找

(4) 比較 85, 比 85 大,從後面找

(5) 比較 117, 等於 117, 找到了節點。

 

具體的搜尋演算法如下: 

 

C代碼  
  1. /* 如果存在 x, 返回 x 所在的節點, 
  2.  * 否則返回 x 的後繼節點 */  
  3. find(x)   
  4. {  
  5.     p = top;  
  6.     while (1) {  
  7.         while (p->next->key < x)  
  8.             p = p->next;  
  9.         if (p->down == NULL)   
  10.             return p->next;  
  11.         p = p->down;  
  12.     }  
  13. }  
 

 

跳錶的插入

先確定該元素要佔據的層數 K(採用丟硬幣的方式,這完全是隨機的)

然後在 Level 1 ... Level K 各個層的鏈表都插入元素。

例子:插入 119, K = 2


 

如果 K 大於鏈表的層數,則要添加新的層。

例子:插入 119, K = 4


 丟硬幣決定 K

插入元素的時候,元素所佔有的層數完全是隨機的,通過一下隨機演算法產生:

 

C代碼  
  1. int random_level()  
  2. {  
  3.     K = 1;  
  4.   
  5.     while (random(0,1))  
  6.         K++;  
  7.   
  8.     return K;  
  9. }  

 

相當與做一次丟硬幣的實驗,如果遇到正面,繼續丟,遇到反面,則停止,

用實驗中丟硬幣的次數 K 作為元素佔有的層數。顯然隨機變數 K 滿足參數為 p = 1/2 的幾何分布,

K 的期望值 E[K] = 1/p = 2. 就是說,各個元素的層數,期望值是 2 層。

 

 

跳錶的高度。

n 個元素的跳錶,每個元素插入的時候都要做一次實驗,用來決定元素佔據的層數 K,

跳錶的高度等於這 n 次實驗中產生的最大 K,待續。。。

 

跳錶的空間複雜度分析

根據上面的分析,每個元素的期望高度為 2, 一個大小為 n 的跳錶,其節點數目的

期望值是 2n。

 

跳錶的刪除

在各個層中找到包含 x 的節點,使用標準的 delete from list 方法刪除該節點。

例子:刪除 71


轉載 http://kenby.iteye.com/blog/1187303

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.