前言:通常我們會遇到一些問題,採用一些標準的資料結構,如雙鏈表、雜湊表或二叉查詢數時,不能夠滿足操作要求,需要對這些資料結構進行擴張,新增一些額外的資訊使得能夠完成新的操作。附加的資訊需要對資料結構的某些操作進行調整,這個是非常關鍵的步驟,決定著資料結構擴張是否能夠實現。本章主要討論了紅黑樹結構的擴張,介紹了兩種擴張方式。第一種方式擴張使得紅黑色能夠支援動態集合上順序統計,快速找出集合中第i小的數,或給出某個元素在集合的全序中的排名。第二種方式擴張使得紅黑色能夠進行區間操作,可以很快地找到集合中覆蓋的區間。關於紅黑色請參考第13章,
1、動態順序統計
在第九章介紹了順序統計的概念,大概的意思是在包含有n個元素的集合中,第i個順序統計量指的是該集合中第i小的元素。在乙個無序的集合中,任意順序統計量都可以在o(n)時間內找到,詳細情況可以參考書中在此基礎上修改紅黑樹的結構,使得任意的順序統計量都可以再o(lgn)時間內確定。向紅黑樹的結構中新增乙個size域,表示包含自身節點的當前節點的子樹節點的數目。這樣修改後可以快速支援順序統計量操作,將這種修改後的紅黑樹叫做:順序統計量樹t。修改後的結構如下所示:
1例如給定紅黑樹的乙個節點x,則size[x] = size[left[x]]+size[right[x]]+1。size[x]為包含以x為根的子樹的節點數(包含x本身),即子樹的大小。如果哨兵定義為0,即設定size[nil[t]]=0。struct
rbtreenode
2;
下面給出乙個修改後的紅黑樹的例子,如下圖所示:
紅黑樹是二叉排序樹,按照中序遍歷從小到大輸出紅黑樹中的關鍵字。從圖中可以看出,新增size域後,很方便看出每個節點的子樹的節點數目(包含自身節點)。書中在後面討論這種結構的操作,分別討論如下:
(1)檢索具有給定排序的元素
過程os_select(x,i)返回乙個指向以x為根的子樹中包含第小關鍵字的結點的指標,即為了找出順序統計量樹t中的第i小關鍵字,可以呼叫os_select(root[t],i)。書中給出了偽**如下:
1該過程類似二分查詢,每一次遞迴呼叫都在順序統計數中下降一層,故最壞情況下os_select的總時間與樹的高度成正比,紅黑樹的高度為lgn。故os_select的執行時間為:o(lgn)。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關鍵字小,則在其右子樹查詢
(2)確定乙個元素的秩(位置)
給定指向一順序統計樹t中節點x的指標,求x在順序統計樹中序遍歷得到的線性序中的位置。書中給出了os_rank(t,x)過程的偽**:
1從程式總可以看出當y == root[t]時候迴圈終止,此時以y為根的子樹是課完整樹,此時r值是這顆整樹中key[x]的秩。while迴圈中的每一次迭代花o(1)時間,且y在每次迭代中沿樹上公升一層,故在最壞情況下0s_rank的執行時間與樹的高度成正比:對含n個節點的順序統計樹時間為o(lgn)。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;
(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...