《演算法導論》讀書筆記之第14章 資料結構的擴張

2022-03-08 14:02:33 字數 3331 閱讀 8823

前言:通常我們會遇到一些問題,採用一些標準的資料結構,如雙鏈表、雜湊表或二叉查詢數時,不能夠滿足操作要求,需要對這些資料結構進行擴張,新增一些額外的資訊使得能夠完成新的操作。附加的資訊需要對資料結構的某些操作進行調整,這個是非常關鍵的步驟,決定著資料結構擴張是否能夠實現。本章主要討論了紅黑樹結構的擴張,介紹了兩種擴張方式。第一種方式擴張使得紅黑色能夠支援動態集合上順序統計,快速找出集合中第i小的數,或給出某個元素在集合的全序中的排名。第二種方式擴張使得紅黑色能夠進行區間操作,可以很快地找到集合中覆蓋的區間。關於紅黑色請參考第13章,

1、動態順序統計

在第九章介紹了順序統計的概念,大概的意思是在包含有n個元素的集合中,第i個順序統計量指的是該集合中第i小的元素。在乙個無序的集合中,任意順序統計量都可以在o(n)時間內找到,詳細情況可以參考書中在此基礎上修改紅黑樹的結構,使得任意的順序統計量都可以再o(lgn)時間內確定。向紅黑樹的結構中新增乙個size域,表示包含自身節點的當前節點的子樹節點的數目。這樣修改後可以快速支援順序統計量操作,將這種修改後的紅黑樹叫做:順序統計量樹t。修改後的結構如下所示:

1

struct

rbtreenode

2;

例如給定紅黑樹的乙個節點x,則size[x] = size[left[x]]+size[right[x]]+1。size[x]為包含以x為根的子樹的節點數(包含x本身),即子樹的大小。如果哨兵定義為0,即設定size[nil[t]]=0

下面給出乙個修改後的紅黑樹的例子,如下圖所示:

紅黑樹是二叉排序樹,按照中序遍歷從小到大輸出紅黑樹中的關鍵字。從圖中可以看出,新增size域後,很方便看出每個節點的子樹的節點數目(包含自身節點)。書中在後面討論這種結構的操作,分別討論如下:

(1)檢索具有給定排序的元素

過程os_select(x,i)返回乙個指向以x為根的子樹中包含第小關鍵字的結點的指標,即為了找出順序統計量樹t中的第i小關鍵字,可以呼叫os_select(root[t],i)。書中給出了偽**如下:

1

os_select(x,i)

2 r = size[left[x]]+1

; //先計算x的處於的位置

3if i =r //x正好是第i小的關鍵字

4 then returnx;5

else

if i

6 then return

os_select(left[x],i)

7else

return os_select(right[x],i-r) //x比第i關鍵字小,則在其右子樹查詢

該過程類似二分查詢,每一次遞迴呼叫都在順序統計數中下降一層,故最壞情況下os_select的總時間與樹的高度成正比,紅黑樹的高度為lgn。故os_select的執行時間為:o(lgn)。

(2)確定乙個元素的秩(位置)

給定指向一順序統計樹t中節點x的指標,求x在順序統計樹中序遍歷得到的線性序中的位置。書中給出了os_rank(t,x)過程的偽**:

1

os_rank(t,x)

2 r = size[left[x]]+1

; //獲取以x為根子樹中x的位置(中序遍歷)

3 y =x;

4while y !=root[t] //從下向上直到根節點5do

if y =right[p[y]] //如果是右子樹

6 then r = r + size[left[p[y]]]+1

; 7 y =p[y]; //向上移動

8return r;

從程式總可以看出當y == root[t]時候迴圈終止,此時以y為根的子樹是課完整樹,此時r值是這顆整樹中key[x]的秩。while迴圈中的每一次迭代花o(1)時間,且y在每次迭代中沿樹上公升一層,故在最壞情況下0s_rank的執行時間與樹的高度成正比:對含n個節點的順序統計樹時間為o(lgn)。

(3)對子樹規模的維護

在紅黑樹中新增size域後,能夠通過os_select和os_rank迅速計算出所需的順序統資訊。通過修改紅黑樹的插入和刪除操作,在此過程是通過旋轉來修改size域。關於這部分需要在紅黑樹的基礎上進行改進,比較複雜,暫時沒有實現。

2、如何擴張資料結構

對一種資料結構的擴張過程分為四個步驟:

1)選擇基礎資料結構

2)確定要在基礎資料結構中新增哪些資訊

3)驗證可用基礎資料結構上的基本修改操作來維護這些新新增的資訊

4)設計新的操作

書中給出了對紅黑樹進行擴張的定理,並給出了證明,這個看的時候有些難度,暫時跳過了。大概意思就是說當紅黑樹被選作基礎資料結構時,某些型別的附加資訊總是可以用插入和刪除來進行有效地維護。

3、區間樹

這小結講的是擴張紅黑樹以支援由區間構成的動態集合上的操作。區間可以很方便的表示各占用一段連續時間的一些事情。區間樹是一種動態集合進行維護的紅黑樹,該集合中的每個元素x都包含在乙個區間int[x]。區間樹支援下列操作:

interval_insert(t,x):將包含區間域int的元素x插入到區間樹t中

interval_delete(t,x):從區間樹t中刪除元素x

interval_search(t,i):返回乙個指向區間樹t中元素x的指標,使int[x]與i重疊,若集合中無此元素存在,則返回nil[t]。

修改紅黑樹得到的區間樹如下圖所示:

從圖可以看出,對區間樹以每個節點的左端點值進行中序變數即可得到有序的序列。有了區間樹的結果就很容易實現其相關操作。

4、總結

本章主要是介紹一種資料結構擴張的方法,靈活性非常之大。以紅黑樹作為例子,我是在年前看的紅黑樹,並給以實現。年後了,對紅黑樹忘了差不多了。呵呵,真是一天不學習,趕不上啦。本章看完比較鬱悶,沒有去實現。實現的難度非常具有挑戰性,何時能夠實現,我心裡有些忐忑。肯定不會放棄,一定會找個時間把這些實現一下。

讀書筆記 演算法導論

第2章演算法入門 浮於表面不如深入其中,送給自己,自己是最大的敵人,那麼就盡最大努力去克服自己,沉思,冷靜,不浮躁!勘誤 在演算法導論第9頁,扼要的扼 內容提要 1 偽 的表示方法 2 插入排序演算法分析 3 迴圈不變式 4 演算法設計之分治法 divide and conquer 5 合併排序演算...

《演算法導論》讀書筆記之第15章 動態規劃 總結

前言 書中列舉四個常見問題,分析如何採用動態規劃方法進行解決。今天把動態規劃演算法總結一下。關於四個問題的動態規範分析過程可以參考前面的幾篇日誌,鏈結如下 裝配線排程問題 矩陣鏈乘問題 最長公共子串行問題 最優二叉查詢樹問題 1 基本概念 動態規劃是通過組合子問題的解而解決整個問題的,通過將問題分解...

APUE讀書筆記 第14章 高階I O

14.1 引言 高階i o包括非阻塞i o 記錄鎖 系統v流機制 i o多路轉換 select和poll函式 readv和writev函式以及儲存對映i o mmap 14.2 非阻塞i o 非阻塞i o使我們可以呼叫open read和write這樣的i o操作,並使這些操作不會永遠阻塞 14.3...