算法導論讀書筆記(16)

http://www.cnblogs.com/sungo

算法導論讀書筆記(16)

動態順序統計

之前介紹過 順序統計 的概念。在一個無序的集合中,任意的順序統計量都可以在 O ( n )時間內找到。而這裏我們將介紹如何在 O ( lg n )時間內確定任意的順序統計量。

下圖顯示的是一種支持快速順序統計量操作的數據結構。一棵 順序統計樹 T 通過在紅黑樹的每個結點中存入附加信息而成。在一個結點 x 內,增加域x.size 。該域包含以結點 x 爲根的子樹的(內部)結點數(包括 x 本身),即子樹的大小。設 T.nil.size 爲0,則有

x.size = x.left.size + x.right.size + 1


檢索具有給定排序的元素

過程 OS-SELECT(x, i) 返回一個指向以 x 爲根的子樹中包含第 i 小關鍵字的結點的指針。爲找出順序統計樹 T 中的第 i 小關鍵字,調用過程 OS-SELECT(T.root, i) 。

OS-SELECT(x, i)
1 r = x.left.size + 1
2 if i == r
3     return x
4 elseif i < r
5     return OS-SELECT(x.left, i)
6 else
7     return OS-SELECT(x.right, i)

對含 n 個元素的動態集合, OS-SELECT 的運行時間爲 O ( lg n )。

確定一個元素的秩

給定指向一順序統計樹 T 中結點 x 的指針,過程 OS-RANK 返回在對 T 進行中序遍歷後得到的線性序中 x 的位置。

OS-RANK(T, x)
1 r = x.left.size + 1
2 y = x
3 while y != T.root
4     if y == y.p.right
5         r = r + y.p.left.size + 1
6     y = y.p
7 return r

x 的秩可以視爲在對樹的中序遍歷中,排在 x 之前的結點個數再加1( x 本身)。在最壞情況下,對含 n 個結點的順序統計樹, OS-RANK 的運行時間爲 O ( lg n )。

區間樹

在算法設計過程中,經常需要對基本的數據結構進行擴張,以便支持一些新功能。而對一種數據結構的擴張過程通常可以分爲四個步驟:

  1. 選擇基礎數據結構
  2. 確定要在基礎數據結構中添加哪些信息
  3. 驗證可用基礎數據結構上的基本修改操作來維護這些新添加的信息
  4. 設計新的操作

以上只是給出了一個一般模式,設計順序統計樹時,我們就依照了這些步驟。

在這裏,我們要擴展紅黑樹以支持由區間構成的動態集合上的操作(假設區間都是閉區間)。一個 閉區間 是一個實數的有序對[ t1, t2 ],其中 t1 <= t2 。我們可以把一個區間[ t1, t2 ]表示成一個對象,其各個域爲 i.low = t1 (低端點), i.high = t2 (高端點)。任意兩個區間 i 和 i' 都滿足 區間三分法 ,即:

  • i 和 i' 重疊( i.low <= i'.high ,且 i'.low <= i.high )
  • i 在 i' 左邊( i.high < i'.low )
  • i 在 i' 右邊( i'.high < i.low )

區間樹是一種對動態集合進行維護的紅黑樹,該集合中的每個元素 x 都包含一個區間 x.int 。區間樹支持下列操作:

  • INTERVAL-INSERT(t, X) :將包含區間域 int 的元素 x 插入到區間樹 T 中。
  • INTERVAL-DELETE(T, x) :從區間樹 T 中刪除元素 x 。
  • INTERVAL-SEARCH(T, i) :返回一個指向區間樹 T 中元素 x 的指針,使 x.int 與 i 重疊;否則返回 T.nil 。

下面就按之前提到的四個步驟,來分析和設計區間樹上的各種操作。

步驟1:基礎數據結構

基礎數據結構爲紅黑樹,其中每個結點 x 包含一個區間域 x.int , x 的關鍵字爲區間的低端點 x.int.low 。

步驟2:附加信息

每個結點還要包含一個值 x.max ,即以 x 爲根的子樹中所有區間的端點的最大值。

步驟3:維護信息

必須驗證對含 n 個結點的區間樹的插入和刪除能在 O ( lg n )時間內完成。給定區間 x.int 和 x 的子結點的 max 值,可以確定 x.max = max ( x.int.high ,x.left.max , x.right.max )。

步驟4:設計新操作

唯一需要的新操作是 INTERVAL-SEARCH 。

INTERVAL-SEARCH(T, i)
1 x = T.root
2 while x != T.nil and i does not overlap x.int
3     if x.left != T.nil and x.left.max >= i.low
4         x = x.left
5     else
6         x = x.right
7 return x
shawk/p/3759986.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章