109 年 國立暨南國際大學資訊工程學系碩士班《資料結構與演算法》
第 1 題
The sequence F(n) of Fibonacci numbers is defined by the recurrence relation
,
with seed values
, and .
a. If using a recursive method to calculate the value of , how many times of additive operations will be performed? Explain your answer briefly. (15%)
b. If using the dynamic programming method to calculate the value of , how many times of additive operations will be performed? Explain your answer briefly. (15%)
登入後即可作答並保存紀錄。
核心觀念
本題比較兩種計算 Fibonacci 數列的方法:
- 遞迴法:同一個子問題會被重複計算。
- 動態規劃法:每個 只計算一次,並儲存已求出的結果。
題目定義為:
且
每次計算 ,就會執行一次加法運算。
解題方法
a. 使用遞迴法計算
令 表示以純遞迴方式計算 時所執行的加法次數。
當 或 時,直接回傳種子值,不需加法:
當 時,除了計算 與 ,還需執行目前這一層的 1 次加法,因此:
逐步計算:
因此,純遞迴法計算 時,會執行:
也可從遞迴樹理解:每個非基底節點都代表一次加法,而遞迴樹中的非基底節點數即為 232。
b. 使用動態規劃法計算
第 2 題
For an AVL tree, write a C-like pseudo-codes to determine which one of the R-R, L-L, R-L, L-R rotations should be performed. Explain your answer briefly. (25%)
登入後即可作答並保存紀錄。
核心觀念
AVL tree 是一棵二元搜尋樹,且每個節點都必須滿足平衡條件。對節點 定義平衡因子:
其中 表示子樹高度。
AVL tree 的合法範圍為:
插入或刪除節點後,若某節點 的平衡因子超出範圍,就必須透過旋轉恢復平衡。旋轉類型取決於:
- 失衡節點 是左重或右重;
- 造成失衡的子節點 是左重或右重。
四種情況如下:
| 情況 | 失衡方向 | 子樹方向 | 修正方式 |
|---|---|---|---|
| L-L | 左左 | 的左子樹之左側 | 對 做右旋 |
| R-R | 右右 | 的右子樹之右側 | 對 做左旋 |
| L-R | 左右 | 的左子樹之右側 | 先對 左旋,再對 右旋 |
| R-L | 右左 | 的右子樹之左側 | 先對 右旋,再對 左旋 |
解題方法
設 為從插入或刪除位置往樹根方向移動時,第一個失衡的節點,設 為 的較高子節點。
使用平衡因子判斷:
- : 左重。
- :L-L。
- :L-R。
- : 右重。
- :R-R。
- :R-L。
在插入情況下,也可直接依照新節點與 、 的鍵值大小判斷;但使用子節點的平衡因子更一般,亦適用於刪除後的重新平衡。
判斷旋轉類型的 C-like pseudo-code
enum RotationType {
NONE,
LL,
RR,
LR,
RL
};
int balanceFactor(Node *v) {
if (v == NULL)
return 0;
return height(v->left) - height(v->right);
}
RotationType determineRotation(Node *z) {
int bz = balanceFactor(z);
// z 左重
if (bz > 1) {
int by = balanceFactor(z->left);
// 左子樹左重或平衡
if (by >= 0)
return LL;
// 左子樹右重
return LR;
}
// z 右重
if (bz < -1) {
int by = balanceFactor(z->right);
// 右子樹右重或平衡
if (by <= 0)
return RR;
// 右子樹左重
return RL;
}
return NONE;
}
其中, 的情況主要會出現在刪除節點後,因此:
- 左重時以 判定為 L-L;
- 右重時以 判定為 R-R。
執行對應旋轉
Node* rebalance(Node *z) {
int type = determineRotation(z);
switch (type) {
case LL:
// 對 z 做右旋
return rotateRight(z);
case RR:
// 對 z 做左旋
return rotateLeft(z);
case LR:
// 先左旋 z 的左子樹,再右旋 z
z->left = rotateLeft(z->left);
return rotateRight(z);
case RL:
// 先右旋 z 的右子樹,再左旋 z
z->right = rotateRight(z->right);
return rotateLeft(z);
case NONE:
default:
return z;
}
}
四種情況說明
1. L-L 情況
若:
第 3 題
For the problem of "Finding the Convex Hull", give a comparison between the Package Wrapping Method and the Graham's Scan Method. Explain your answer in detail. (25%)
登入後即可作答並保存紀錄。
核心觀念
在計算幾何(Computational Geometry)中,凸包問題(Convex Hull Problem)是基礎且核心的研究主題:
給定二維平面上包含 個點的集合 ,凸包 是包含 中所有點的最小凸多邊形。求解凸包即為依序(順時針或逆時針)找出構成此凸多邊形邊界的頂點集合。令 為輸入點的總數, 為最終凸包上的頂點個數()。
本題比較求解凸包的兩種經典演算法:
- Package Wrapping Method(禮物包裝法,又稱 Jarvis March):屬於輸出敏感演算法(Output-Sensitive Algorithm),利用類似用繩子將外圍點逐步纏繞包裹的直觀幾何操作。
- Graham's Scan Method(葛立恆掃描法):屬於基於排序的演算法(Sorting-Based Algorithm),透過極座標角度預先排序,並利用**堆疊(Stack)**進行線性單調掃描與回溯。
兩者在底層判斷「轉折方向」時,皆依賴三點的外積(Cross Product)或行列式運算( 測試):
- :代表從向量 到 為逆時針轉折(左轉)。
- :代表為順時針轉折(右轉)。
- :代表三點共線(Collinear)。
解題方法:演算法步驟詳解
1. Package Wrapping Method (Jarvis March)
- 步驟 1(找起點):從點集 中找出一個保證在凸包上的極值點 (通常選 座標最小者;若有相同者則取 座標最小者)。
- 步驟 2(尋找下一點):令當前凸包頂點為 。在剩下的點中挑選一個點 ,使得對所有 ,向量轉折皆滿足 (即所有點都在射線 的同一側/最外側逆時針方向)。
- 步驟 3(迭代包裝):將 加入凸包頂點序列,並令 。
- 步驟 4(終止條件):重複步驟 2 與 3,直到選出的下一個頂點繞回起始點 為止。
2. Graham's Scan Method
- 步驟 1(找基準點):找出 座標最小(若相同則選 座標最小)的點作為基準點 。
- 步驟 2(極角排序):計算其餘 個點相對於 的極座標角度(Polar Angle),並按角度由小到大排序;若有極角相同者,僅保留距離 最遠的點。
- 步驟 3(初始化堆疊):建立一個堆疊 ,依序將基準點 及排序後的前兩點 推入(Push)堆疊中。
- 步驟 4(單調掃描):對排序後的其餘各點 ():
- 檢查堆疊次頂端點()、頂端點()與當前點 的轉向關係。
- 當 (非左轉,即右轉或共線)時,代表 必定落於多邊形內部,將 彈出(Pop)。
- 重複彈出直到構成嚴格左轉,接著將 推入堆疊。
- 步驟 5(產出結果):所有點掃描完成後,堆疊中留存的點即為凸包頂點。
詳細比較分析
兩演算法的各項指標對比如下表所示:
| 比較項目 | Package Wrapping (Jarvis March) | Graham's Scan |
|---|---|---|
| 設計典範 | 貪婪搜尋 / 輸出敏感型(Output-Sensitive) | 預處理排序 + 堆疊單調掃描(Incremental/Scan) |
第 4 題
How many different binary trees can be made from 5 nodes? Explain your answer. (20%)
登入後即可作答並保存紀錄。
核心觀念
本題考查「具有 個節點的不同二元樹數量」,其結果由 Catalan 數(卡特蘭數)給出。
二元樹的每個節點最多有左子樹與右子樹,且左、右子樹的位置不同,因此交換左右子樹會形成不同的二元樹。
具有 個節點的二元樹數量為:
其中 為第 個 Catalan 數。
解題方法:使用遞迴關係
設 表示具有 個節點的不同二元樹數量。
固定一個根節點後,剩下的 個節點必須分配到左子樹與右子樹。若左子樹有 個節點,右子樹就有 個節點,因此:
初始條件為:
代表空樹只有一種結構。
依序計算:
因此: