--- tags: 資料結構 --- ![](https://i.imgur.com/GHlVjVM.jpg) # 資料結構 第十章 搜尋結構 ## 一、最佳二元搜尋樹 ### (一)用意: 在資料相同下,不同的二搜尋元樹會有不同的形態,(1/(n+1))*C(2n,n)種,為了搜尋效益討論如何取出最佳的搜尋二元樹。 ### (二)圖示: 若以比較次數來判斷 a圖成本=((1*1)+(2*2)+(3*1)+(4*1))/5 = 2.4 b圖成本=((1*1)+(2*2)+(3*2))/5 = 2.2 b圖二元樹成本將優於a圖 ![](https://i.imgur.com/mvVQLzx.jpg) ### (三)加入外部節點討論 ![](https://i.imgur.com/HZMdQ80.jpg) #### 1、內部路徑長度(I) 以a圖為例: I = 0+1+1+2+3 = 7 (for+do+while+noid+if) #### 2、外部路徑長度(E) 以a圖為例: E = 2+2+4+4+3+2 =17 #### 3、E = I + 2n ### (四)名詞定義: #### 1、P~i~ = 成功搜尋二元樹機率 (root level為1) 成功搜尋節點的比較次數 level (成本=比較次數*機率) 成功搜尋節點的總成本 = 搜尋每個節點成本*機率的總和 ![](https://i.imgur.com/ZmphoGq.jpg) #### 2、Q~i~ = 搜尋失敗的機率 (root level為1) 失敗節點比較次數 level-1 (成本=比較次數*機率) 搜尋失敗的總成本= 每個失敗節點成本*機率的總和 ![](https://i.imgur.com/v9HI0OH.jpg) #### 3、二元搜尋樹總成本 失敗機率+成功機率=100% ![](https://i.imgur.com/O1iCRXv.jpg) 總成本=成功搜尋成本+失敗搜尋成本 ![](https://i.imgur.com/DEBClEc.jpg) #### 4、a~1~<a~2~<...<a~n~ N個內部節點 #### 5、E~0~,E~1~,...,E~n~ N個外部節點 #### 6、T~ij~ =a~i+1~,a~i+2~,...,a~j~內部節點建立最佳二元搜尋樹 #### 7、T~0n~:最終的最佳二元搜尋樹 #### 8、T~ii~:為一個空樹(只有一個失敗節點) #### 9、C~ij~:最佳二元搜尋樹的總成本 #### 10、R~ij~:T~ij~的樹根 #### 11、W~ij~:T~ij~的加權總合 ### (五)C~ij~公視推導 #### 1、令a~k~為root那C~ij~ 等於 左子樹成本+右子樹成本+(左子樹權重+右子樹權重),因為左右子樹成本若加上a~k~那所有點的level皆會增加1 ![](https://i.imgur.com/qA9req9.jpg) #### 2、W~ij~=T~ij~的加權總合,C~ij~挑選完root分成左右子樹,從全部的組合中挑出成本最小的樹 ![](https://i.imgur.com/amzAgyv.jpg) ### (六)推倒表格及畫圖 ![](https://i.imgur.com/vMvpVtb.jpg) ## 二、AVL樹 ### (一)用途 月份插入的順序不同,會產生以下兩種極端的例子(高度最小及最大),為了讓搜尋更有效,控制樹的高度平衡,才不會有斜曲樹出現。 ![](https://i.imgur.com/qUQhk1R.jpg) ![](https://i.imgur.com/64HNSj2.jpg) ### (二)定義 若為空樹則為高度平衡樹,若非空則左右子樹必須滿足 1、左右子樹皆為高度平衡樹 2、|左子樹高度-右子樹高度|≦ 1 ### (三)平衡因子(balance factor) 若為高度平衡樹 左子樹高度-右子樹高度 只會= -1 ,0 ,1 ### (四)調整(旋轉) #### 1、當平衡因子達到+2 or -2 時,表示此樹不為高度平衡樹,故須調整成高度平衡,利用旋轉資料來調整樹的高度分別為LL、RR、LR、RL旋轉 #### 2、圖示: ![](https://i.imgur.com/3EvBPph.jpg) ![](https://i.imgur.com/HLJ8Wqv.jpg) ![](https://i.imgur.com/4Jg2hdQ.jpg) ![](https://i.imgur.com/FHyJrCo.jpg) 每次插入時都保持為高度平衡樹,最後插入調整完結果 ![](https://i.imgur.com/NRLglyU.jpg) ### (五)重新調整平衡圖示: ![](https://i.imgur.com/fod6xws.jpg) ![](https://i.imgur.com/HK2d0Od.jpg) ![](https://i.imgur.com/gYzK8Tu.jpg) ### (六)時間複雜度 ![](https://i.imgur.com/546D0Wx.jpg) ## 三、2-3樹 每個內部節點都有 2-3 degree (2-node表示degree為2的點) (3-node表示degree為3的點) ### (一)定義 #### 1、說明 若為空樹為2-3樹,若不為空樹則須滿足 (1)每一個內部節點的degree為2或3 2-node節點內有一筆資料 3-node節點內有二筆資料 (2)若為2-node,那左子點的鍵值<中子點的鍵值 (3)若為3-node,那左子點的鍵值<中子點的鍵值<右子點的鍵值 (4)所有外部節點屬於同一個level (5)root最少需要2個子點最多3個 #### 2、圖示 ![](https://i.imgur.com/ofym74j.jpg) ### (二)搜尋 從root搜尋比較鍵值1、鍵值2看大小決定前往左子點or中子點or右子點,與二元搜尋樹相似故時間複雜度為O(logn) ### (三)插入 #### 1、插入 以上圖插入70與30為例 ##### (1)圖(a) 插入葉子後並無溢位 ##### (2)圖(b) 插入葉子後產生(4-node)節點內有三筆資料,需做調整,調整則為將3筆資料大小位於中間鍵值向父點移動,其餘兩鍵值分別變成左右子點,若此時父點一樣溢位則再執行一次(如下圖再插入60)。 ![](https://i.imgur.com/APMFSuN.jpg) ### (四)刪除 #### 1、刪除葉節點內的值 ![](https://i.imgur.com/Rshev8Q.jpg) #### 2、若葉節點刪除後為空時 使用兄弟(找左子點最大or右子點最小來)替換root鍵值,再從root被替換的鍵值下放至葉子 ![](https://i.imgur.com/H1omC14.jpg) ![](https://i.imgur.com/KQG1Hkp.jpg) ## 四、2-3-4樹 2-3樹的進階 每個內部節點都有 2-4 degree (2-node表示degree為2的點) (3-node表示degree為3的點) (4-node表示degree為4的點) ### (一)定義 #### 1、說明 若為空樹為2-3-4樹,若不為空樹則須滿足 (1)每一個內部節點的degree為2或3或4 2-node節點內有一筆資料 3-node節點內有二筆資料 4-node節點內有三筆資料 (2)若為2-node,那左子點的鍵值<樹根鍵值<中子點的鍵值 (3)若為3-node,那左子點的鍵值<樹根左鍵值<中子點的鍵值<樹根右鍵值<右子點的鍵值 (4)若為4-node,那左子點鍵值<樹根左鍵值<左中子點的鍵值<樹根中鍵值<右中子點的鍵值<樹根右鍵值<右子點的鍵值 (5)所有外部節點屬於同一個level (6)root最少需要2個子點最多m個 #### 2、圖示 ![](https://i.imgur.com/udwOeBY.jpg) ### (二)插入 搜尋由上到下若遇到4-node需要做調整至最後,插入至葉節點,插入後就不需要做調整, #### 1、遇到4-node情形有3種情況 #### (1)4-node為2-3-4樹的root ![](https://i.imgur.com/GXBS8dY.jpg) #### (2)4-node的父點為2-node ![](https://i.imgur.com/gJaTzWM.jpg) #### (3)4-node的父點為3-node ![](https://i.imgur.com/7ahcL3u.jpg) ### (三)刪除 #### 1、步驟 ##### (1)定義 節點有 2-3-4 degree (鍵值1-2-3) m = 分支度 樹葉分支度最小值 = ⌈m/2⌉ = 2 樹葉最少鍵值數量為 1 (degree 2 = 鍵值最少為1) p為q之父點 ##### (2)刪除考量的狀況 ###### a、當p為葉子確保葉子鍵值至少為1(2-node、degree為2),若p為為Root刪除後為空樹 ###### b、q不是(2-node)刪除後q仍至少有1個鍵值(>最小鍵值)故不需調整 ###### c、若q(p左子)為(2-node)若r(p右子)也為(2-node)則將p(2-node)qr合成(4-node) ###### d、同上若p(3-node or 4-node)則從p分點至q ###### e、若q(p左子)為(2-node)若r(p右子)為(3-node or 4-node)則以r節點鍵值補至樹根p,再由樹根補給q。 #### 2、圖示 ![](https://i.imgur.com/jsrT3dC.jpg) ## 五、紅黑樹 ### (一)定義 #### 1、為2-3-4樹的變形(轉換如下圖) 3-node(轉換不唯一) ![](https://i.imgur.com/QtRmn32.jpg) #### 2、紅黑樹性質(以節點為顏色) ##### (1)為二元搜尋樹 ##### (2)從樹根至外部節點具有相同數量的黑色節點 ##### (3)從樹根至外部節點沒有具2個或多個連續紅色節點 #### 3、圖示(以鏈結為顏色) 虛線-紅色 實線-黑色 ##### (1)為二元搜尋樹 ##### (2)外部節點rank為0 ##### (3)每個外部節點的父點(內部節點)rank為1 ##### (4)x的父點p的rank = rank(x)≦rank(p(x))≦rank(x)+1 ##### (5)x的祖父點gp的rank = rank(x) < rank(gp(x)). rank = 從外部節點至該點所需要的距離 同rank為紅色link ### (二)搜尋 搜尋方式與二元搜尋樹相等 ### (三)插入 使用二元搜尋樹方式插入紅色節點鍵值,若有連續2個紅點則做調整。 ### 1、調整 LLb,LLr、LRb,LRr、RRb,RRr、RLb,RLr 共有8種 (左點至父點分支 父點至x點分之 x父點的兄弟) #### (1)變色調整 LLr,LRr,RRr,RLr (變色) 祖點變紅,父點與父點兄弟改成黑色 ![](https://i.imgur.com/uaVrLA2.jpg) #### (2)旋轉調整 LLb,LRb,RRb,RLr (旋轉) 依大小旋轉後,父點更改為黑色,2個子點更改成紅色。 ![](https://i.imgur.com/Y30P50Q.jpg) #### (3)樹根為黑色 一路調整至樹根,若樹根為紅色節點則直接更改成黑色,則調整完畢。 >資料結構16-2(國立中山大學楊昌彪教授,有中文字幕) - Red-Black Trees > ### (四)刪除 紅色節點可以直接刪除 刪除為黑色節點則先旋轉or變色再刪除 ## 六、B樹 ### (一)m-way搜尋樹定義 空樹為m-分支搜尋樹,若不為空樹則m-分支搜尋數須滿足以下條件: (1)所有節點分支度 ≦ m (最多有m個兒子) (2)一個節點最多可儲存m-1筆資料 (3)最左子點<第1鍵值<第二左子點<第2鍵值<...<第m-1鍵值<最右子點 (4)所有子樹皆為m-way搜尋樹 ### (二)定義 B樹為m-way搜尋數的一種,空樹亦是,若非空則滿足 (1)樹根至少需要2個子點 (2)除了樹根與失敗節點,其餘節點鍵值數量至少需要⌈m/2⌉-1,至少需要⌈m/2⌉個子點 (3) ### (三)插入 與2-3樹的規則一樣,插入後至節點鍵值已滿做分裂 ### (四)刪除 與2-3樹的規則一樣,刪除後節點鍵值須保持⌈m/2⌉-1個。 case1:若不足向左右兄弟節點借(Ex:左子鍵值給樹根,樹根鍵值補至不足的子點) case2:若不足左右兄弟節點也不足的情況下,則一邊做合併。 ## 七、斜張樹 雖然高度平衡樹最差O(logn),則斜張樹則是平均分攤為O(logn),每次運算完透過調整旋轉節點至樹根,來降低時間複雜度。 ### (一)調整的節點選擇 #### 1、成功搜尋的節點 #### 2、失敗搜尋最後比較的節點 #### 2、新插入的節點 #### 3、刪除節點的父點 ### (二)調整範例 ![](https://i.imgur.com/Zw2h7Nn.jpg) ![](https://i.imgur.com/cSP1H2N.jpg) ## 八、數字(數位;位元)搜尋樹 ### (一)位元樹搜尋 位元搜尋樹,每個節點都有一個鍵值,高度每增加一層(則由左至右每層固定一個bit討論),往左為0往右為1。 ![](https://i.imgur.com/4An37xk.jpg) ![](https://i.imgur.com/dzhqdHZ.jpg) ![](https://i.imgur.com/DSLWsy4.jpg) >參考資料 https://opendatastructures.org/ods-cpp/13_1_digital_search_tree.html ### (二)binary trie(二元字典樹) 筆者自己翻譯(透過每次的True(1) or False(0) )來決定最後搜尋鍵值,結構類似二元樹及賀夫曼樹,透過分支搜勳到最後(葉節點or外部節點)得到鍵值。 ![](https://i.imgur.com/IvR6ms7.jpg) ### (三)Patricia (壓縮二元字典樹) 將無外部鍵值的節點省略已達到降低樹高 ![](https://i.imgur.com/F32Yuad.jpg) #### 1、Patricia圖形製作 (1)消除節點上的元素 (2)將資料儲存至分支上 (3)因壓縮每條路徑分支比節點數-1故選出一個頭節點(所有點都是頭節點的左子樹) ![](https://i.imgur.com/5prIO2x.jpg) #### 2、插入 ![](https://i.imgur.com/LqLHHAI.jpg) ## 九、字典樹 ### (一)定義圖示:(level 4) ![](https://i.imgur.com/Wgdqsl4.jpg) ### (二)搜尋: 如上圖搜尋字串,用字母向下搜尋至找到字串資料(像查字典一樣) 時間複雜度:O(字串所在level(高度)) ### (三)抽樣: 利用取部分來降低樹高level #### 1、從字尾部開始:(level 2) ![](https://i.imgur.com/PdFMgKF.jpg) #### 2、挑選皆不同的位元:(level 1) ![](https://i.imgur.com/vj6Jy5g.jpg) --- ![](https://i.imgur.com/WgpVgFp.jpg) --- ### (四)插入 ![](https://i.imgur.com/kIHEptp.jpg) ### (五)刪除 如上圖若要刪除"bobwhite"只要將第二個陣列索引 O 鏈結改成NULL即可 > 參考資料:Fundamentals of Data Structures in C by Ellis Horowitz, Sartaj Sahni, Susan Anderson-Freed