在應用工程中,需要在現有的資料結構上有所創新,但很少需要創造出全新的資料結構。通常情況下,只要向標準的資料結構中增加一些資訊即可。可以對資料結構編入新的造作,以支援所需的應用。但是,資料結構的擴張並不總是輕而易舉,附加的資訊需要能為該資料結構的常規操作所更新和維護。這一章討論通過擴充紅/黑樹狀結構構造的資料結構。
動態順序統計
第9章介紹了順序統計的概念,在一個無序的集合中,任意的順序統計量都可以在O(n)時間內找到。在這一節裡,將介紹如何修改紅/黑樹狀結構的結構,使得任意的順序統計量都可以在O(lgn)時間內確定。
一棵順序統計量樹T通過簡單地在紅/黑樹狀結構的每個結點存入附加資訊而成。在一個結點x內,除了原有的域,還包括size[x],這個域包含以結點x為根的子樹的節點數:
Size[x] = size[left[x]] + size[right[x]] +1
檢索具有給點排序的元素演算法如下,只要調用OS-SELECT(root[T],i):
OS-SELECT(x, i)
1 r = size[left[x]]+1
2 if i = = r
3 then return r
4 Else if i<r
5 Then return OS-SELECT(left[x],i)
6 Else return OS-SELECT(right[x],i-r)
確定一個元素的秩:
OS-RANK(T, x)
1 r = size[left[x]]+1
2 y = x
3 while y != root[T]
4 do if y==right[p[y]]
5 then r = r+size[left[p[y]]]+1
6 y = p[y]
7 return r
對子樹規模的維護:
給點每個結點的size域後,OS-SLELECT和OS-RANK能迅速地計算出所需的順序統計資訊。然而,除非能夠用紅/黑樹狀結構上基本的修改操作對這些size域加以有效維護,否則,就達不到期望的目的。
插入結點:在尋找插入位置的過程中,所經路徑上的結點size域都需加1
旋轉:如果插入結點後,需要旋轉某些結點,可以驗證,可以在常數時間內更新相關結點的size域。
如何擴張資料結構
對一種資料結構進行擴張,一般分為四個步驟
1 選擇基礎資料結構
2 確定選取什麼資訊作為關鍵字,選取什麼資訊作為附加欄位,這些選擇取決於設計目的
3 驗證可在資料結構的常規操作中來維護新加的資訊,一般來說如果某個資訊只直接依賴於其子節點的資訊的話,維護某個節點該資訊只需要常數時間。
4 設計新的操作
以上節的順序統計樹為例,我們不是在結點中儲存順序統計量,而是儲存子樹的節點數,這是因為前者很難維護。而有了後者我們也可以在較快時間lgn內得出順序統計量。
區間樹:
一個閉區間是一個實數的有序對[t1,t2],其中t1<=t2。區間可以很方便第表示佔用連續時間的事件。我們可以把一個區間[t1,t2]表示成一個對象i,其各個域為low[i]=t1,high[i]=t2。兩個區間i和j滿足一下三種關係之一:
1 重疊
2 i在j左邊,即high[i]<low[j]
3 i在j右邊,即high[j]<low[i]
我們需要維護一個動態區間集合,並能迅速找到與某個已知區間重疊的集合元素。
先按上節所述的方法來構造區間樹:
1 基礎資料結構
選擇紅/黑樹狀結構,其中每個結點x包含區間域int[x],關鍵字為區間的低端點low[int[x]]。這樣對樹進行中序遍曆就可以按低端點的次序輸出區間。
2 附加資訊
每個結點除了區間資訊之外,還包含一個值max[x],即以x為根的子樹所有區間的端點的最大值。
3 對資訊的維護
驗證對max域的維護能在常規的插入、刪除操作中完成:
max[x] = max( high[int[x]], max[left[x]], max[right[x]]),這樣更新max域只需要常數時間。
4 新的操作
INTERVAL-SEARCH(T, i)
1. x root[T]
2. while x!=nil[T] and i dose not overlap int[x]
3. do if left[x] != nil[T] and max[left[x]]>=low[i]
4. then x left[x]
5. else x right[x]
6. return x
上述演算法的關鍵點在於第3-5行的選擇,在結點x與i不重疊前提下,如果x存在左樹,且左子樹的最大端點大於i的低點,則往左子樹搜尋:這個選擇是正確的,應為如果在這種條件下左子樹中不存在和i重疊的結點,右子樹種也不會存在。因為max[left[x]]>=low[i],左子樹中必然存在某結點y,high[y]>=low[i],如果y與i不重疊,則有low[y]>high[i],則x右子樹的所有結點的低端都大於high[i]。