---
# System prepended metadata

title: 資料結構 第十章 搜尋結構
tags: [資料結構]

---

---
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個兒子)
    (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 
