目前常常使用的平衡數據結構有:B樹,紅黑樹,AVL樹,Splay Tree, Treep等。算法
想象一下,給你一張草稿紙,一隻筆,一個編輯器,你能當即實現一顆紅黑樹,或者AVL樹數據結構
出來嗎? 很難吧,這須要時間,要考慮不少細節,要參考一堆算法與數據結構之類的樹,dom
還要參考網上的代碼,至關麻煩。編輯器
用跳錶吧,跳錶是一種隨機化的數據結構,目前開源軟件 Redis 和 LevelDB 都有用到它,優化
它的效率和紅黑樹以及 AVL 樹不相上下,但跳錶的原理至關簡單,只要你能熟練操做鏈表,spa
就能輕鬆實現一個 SkipList。指針
考慮一個有序表:blog
從該有序表中搜索元素 < 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, 找到了節點。
具體的搜索算法以下:
先肯定該元素要佔據的層數 K(採用丟硬幣的方式,這徹底是隨機的)
而後在 Level 1 ... Level K 各個層的鏈表都插入元素。
例子:插入 119, K = 2
若是 K 大於鏈表的層數,則要添加新的層。
例子:插入 119, K = 4
插入元素的時候,元素所佔有的層數徹底是隨機的,經過一下隨機算法產生:
至關與作一次丟硬幣的實驗,若是遇到正面,繼續丟,遇到反面,則中止,
用實驗中丟硬幣的次數 K 做爲元素佔有的層數。顯然隨機變量 K 知足參數爲 p = 1/2 的幾何分佈,
K 的指望值 E[K] = 1/p = 2. 就是說,各個元素的層數,指望值是 2 層。
n 個元素的跳錶,每一個元素插入的時候都要作一次實驗,用來決定元素佔據的層數 K,
跳錶的高度等於這 n 次實驗中產生的最大 K,待續。。。
根據上面的分析,每一個元素的指望高度爲 2, 一個大小爲 n 的跳錶,其節點數目的
指望值是 2n。
在各個層中找到包含 x 的節點,使用標準的 delete from list 方法刪除該節點。
例子:刪除 71