寫在前面的話
跳錶實際上是一種非常好使的數據結構,但由於用的人比較少,所以在OI競賽中並不常用,但其效率是很高的。想要深入研究的同學可以研究:
- 《讓算法的效率“跳起來”! 》—— 魏冉
- 《線段跳錶——跳錶的一個拓展》——李驥揚
這兩位大神的論文
跳錶的定義
- 跳錶的每一層都是一個鏈表
- 每一條鏈表的兩端必須是
−∞ 和+∞ - 每條鏈的元素必須包含於序數較低的鏈的元素集合
下圖是一個鏈表
跳錶的搜索操作
跳錶的普通搜索操作
設當前結點爲
跳錶的搜索過程如下:
- 如果
- 如果
- 如果
- 如果
舉一個例子:在上圖中的跳錶中搜索6
跳錶的記憶化搜索操作
跳錶的記憶化搜索就是在普通搜索的基礎上,提取出上一次搜索的每一層的最後一個結點,比如講上述搜索例子中提取可以得到:
其中橙色結點爲每一層的末端。
之後我們找到第一個小於待搜索元素的末端結點,從該結點開始搜索,例如搜索 5 這個元素:
首先找到起始結點:
然後搜索:
這種搜索方式在前後搜索數據有關聯的時候尤爲管用
跳錶的插入操作
跳錶的插入分爲三步:
- 搜索待插入元素
- 在搜索結束的地方插入
- 由隨機決策模塊決定新元素的層數,並向上加層
例如在下圖鏈表中添加元素15:
搜索後得到待插入元素的位置:
插入後運行隨即決策模塊得到層數,比如說是3層,則需要向上增加層數:
於是我們就成功地將15插入到了這個跳錶之中。
然後我們來看隨即決策模塊
給定一個常數P
H <- 0
While True
R <- random(0~1)
If R < P Then
H++
Else Do
Break
End
在這個隨機決策模塊中,我們是從H層按P的概率向上增加層數,所以很容易得到一個性質:
對於一個元素,它所在列的高度大於等於
k 的概率爲Pk−1
這個重要的性質將會在分析複雜度的時候反覆用到。
跳錶的刪除操作
刪除操作就是先查找,找到後刪掉,舉個例子,在下圖的跳錶中刪除元素9: