111 年 國立中央大學資訊工程學系碩士班《資料結構與演算法》
第 1 題5 分
- Which of the following statements are true?
(A) Consider the convert the infix expression a*(b+c/d)(e-f)+g to its postfix form. There are at most 4
tokens in this stack at any moment during the conversion.
(B) The postfix form of infix expression (a+b-c)(d-e) is abc+-de-*
(C) The infix expression of postfix expression 3k-2m4++pab-/ is ((3-k)+2(m+4))/(p*(a-b))
(D) Consider the convert the infix expression a*(b+c/d)*(e-f) to its postfix form. There are at most 3
tokens in this stack at any moment during the conversion.
登入後即可作答並保存紀錄。
核心觀念
本題考驗運算式表示法轉換(Infix to Postfix Conversion)與堆疊(Stack)資料結構應用,核心觀念包含:
- Shunting-yard 演算法:利用堆疊暫存運算子(Operators)與括號(Parentheses)進行中序(Infix)轉後序(Postfix)的處理過程。
- 運算子優先權與結合律(Precedence & Associativity):
- 括號
():當讀取到左括號(時,優先權最高,直接壓入堆疊;但在堆疊內部,(的優先權視為最低,不會被後續的一般運算子彈出。 - 乘除
*,/:優先權高於加減,同階採左至右結合(Left-to-Right)。 - 加減
+,-:優先權低於乘除,同階採左至右結合(Left-to-Right)。
- 括號
- 堆疊最大深度分析:追蹤轉換過程中,堆疊內同時存在的 Token(運算子與括號)數量的上限。
- 後序轉中序(Postfix to Infix Conversion):利用運算元堆疊,由左至右讀取後序運算式,遇到運算子即彈出頂端兩個運算元結合並加括號,還原為標準中序運算式。
解題方法
1. 中序轉後序堆疊運作規則
- 運算元(Operand):直接輸出至後序運算式。
- 左括號
(:直接推入(Push)運算子堆疊。 - 運算子(Operator):若堆疊頂端運算子的優先權大於或等於當前讀入運算子(同優先權依左結合律處理),則將堆疊頂端運算子彈出(Pop)並輸出;重複此檢查直到堆疊頂端優先權較低或為
(,最後將當前運算子推入堆疊。 - 右括號
):不斷彈出堆疊頂端運算子並輸出,直到遇到(為止,並將(彈出丟棄。
2. 後序轉中序堆疊運作規則
- 由左至右掃描後序運算式:
- 遇到運算元:推入運算元堆疊。
- 遇到二元運算子 :從堆疊先後彈出 (右運算元)與 (左運算元),組合成 後推回堆疊。
選項分析
(A) 正確
分析中序運算式 轉後序的堆疊狀態變化:
| 步驟 | 讀入 Token | 動作說明 | 後序輸出結果 | 堆疊內容 (Bottom Top) | 堆疊 Token 數 |
|---|---|---|---|---|---|
| 1 | 運算元,直接輸出 | 0 | |||
| 2 | 壓入堆疊 | 1 | |||
| 3 | 壓入堆疊 | 2 | |||
| 4 | 運算元,直接輸出 | 2 | |||
| 5 | 壓入堆疊 | 3 | |||
| 6 | 運算元,直接輸出 | 3 | |||
| 7 | 優先權 , 壓入堆疊 | 4 | |||
| 8 | 運算元,直接輸出 | 4 | |||
| 9 | 彈出 與 , 彈出 | 1 | |||
| 10 | 頂端同為 ,彈出舊 壓入新 | 1 | |||
| 11 | 壓入堆疊 | 2 | |||
| 12 | 運算元,直接輸出 | 2 | |||
| 13 | 壓入堆疊 | 3 |
第 2 題5 分
- Which of the following statements are true?
(A) Dynamic programming is a technique that avoids the recursive explosion.
(B) Overlapping recursive calls tend to yield exponential algorithm.
(C) Greedy algorithm makes locally optimal decision at each step.
(D) Divide and conquer is a type of recursive algorithm. The recursion is the divide part.
登入後即可作答並保存紀錄。
核心觀念
本題考驗演算法設計典範(Algorithm Design Paradigms)的核心定義與運作機制,主要涵蓋以下四項重點:
- 動態規劃(Dynamic Programming, DP):利用「記憶化(Memoization)」或「填表法(Tabulation)」儲存子問題的解,避免重複計算導致的遞迴爆炸(Recursive Explosion)。
- 重疊子問題(Overlapping Subproblems):若遞迴樹中存在大量重複計算的子問題且未加適當處理,時間複雜度常呈指數級暴增。
- 貪婪演算法(Greedy Algorithm):具備「貪婪選擇性質(Greedy-choice Property)」,在每一步驟中皆做出當下看起來最佳的局部最佳選擇(Locally Optimal Decision)。
- 分治法(Divide and Conquer):標準架構涵蓋 Divide(分)、Conquer(治)、Combine(合)。其中真正進行「遞迴求解」的是 Conquer(治) 階段。
解題方法
本題屬於經典觀念判斷題,解題切入點在於對各演算法概念的標準定義進行比對與驗證:
- 檢視動態規劃是否能將重複子問題的時間複雜度從指數級降低至多項式級,藉此避免遞迴爆炸。
- 評估未經記憶化處理的重疊遞迴呼叫對時間複雜度的影響。
- 確認貪婪演算法的決策模式。
- 剖析分治法三個階段各自對應的演算法行為,釐清遞迴執行的時間點。
選項分析
- (A) 正確
動態規劃(Dynamic Programming) 的核心精神在於解決具有「重疊子問題(Overlapping Subproblems)」的遞迴問題。若採用傳統遞迴,相同子問題會被重複計算多次,造成計算量隨問題規模呈指數型暴增(即 Recursive Explosion)。DP 透過儲存子問題的解答(備忘錄法或填表法),使每個子問題僅需計算一次,成功避免了遞迴爆炸。
第 3 題5 分
- Which of the following statements about n-element AVL trees are false?
(A) The time complexity of rebalancing rotation after deleting an element is 0(log n).
(B) The time complexity of rebalancing rotation after insertion is 0(1og n).
(C) If the AVL tree has height = h, then n <= Fh+2-1, where Fh+2 is the Fibonacci number, i.e., Fh+2=Fh+1+Fh.
(D) hL - hr should be smaller than 1, where hL and hr denote the height of the left subtree and the right
subtree, respectively.
登入後即可作答並保存紀錄。
核心觀念
本題評測考生對 AVL Tree(高度平衡二元搜尋樹) 之核心性質與推導的理解,涵蓋三大要點:
- 平衡條件(Balance Property):任意節點之左右子樹高度差絕對值不可超過 1,即平衡因子(Balance Factor)。
- 重平衡旋轉時間複雜度(Rebalancing Complexity):
- 插入(Insertion):至多進行 1 次單旋轉或雙旋轉,時間複雜度為 。
- 刪除(Deletion):可能引發向根節點傳遞的連鎖旋轉(Cascading Rotations),最多需 次旋轉,時間複雜度為 。
- 樹高與最少節點數關係(Fibonacci Tree 結構):高度為 的 AVL 樹,其最少節點數符合費氏數列(Fibonacci Sequence)遞迴關係,構成節點數的 下界(Lower Bound)。
解題方法
本題要求找出 錯誤(false) 的選項。解題切入點如下:
- 複雜度分析:區分「插入」與「刪除」元素後恢復平衡所需的旋轉次數與連鎖效應(Cascading Effect)。
- 數學公式證明:推導高度為 的最疏鬆 AVL 樹(Fibonacci Tree)之最小節點數遞迴式 ,檢驗節點數 與費氏數列 的不等式方向。
- 邏輯與邊界檢查:對照 AVL 樹平衡因子的精準數學定義,檢驗不等式符號與邊界值(如 )。
選項分析
-
(A) 正確(非本題所求之錯誤選項)
- 原文:The time complexity of rebalancing rotation after deleting an element is O(log n).
- 解析:在 AVL 樹中刪除一個節點後,執行旋轉重平衡可能會使該子樹的高度減少 1,進而打破父節點或更上層祖先節點的平衡。最壞情況下,此不平衡會一路向上傳遞至根節點(稱為 Cascading Rotations),最多需要進行 次旋轉。由於每次旋轉僅需 時間,故刪除後旋轉重平衡的總時間複雜度為 。故本敘述正確(True)。
-
(B) 錯誤(為本題答案)
- 原文:The time complexity of rebalancing rotation after insertion is O(log n).
- 解析:在 AVL 樹中插入一個節點後,至多只需要進行 1 次旋轉(單旋轉或雙旋轉),即可將該子樹的高度恢復至插入前的高度,不會將不平衡繼續向上傳遞。因此,插入後進行旋轉重平衡的時間複雜度應為 。將其標示為 未能反映 的精準旋轉次數特性(考題常以此對比插入 與刪除 之差異)。故本敘述錯誤(False)。
第 4 題5 分
- Consider a height-biased leftist tree (HBLT). Let w(x) be the number of internal nodes in the subtree with
root x. Which of the following statements are false?
(A) The length of the lefttmost path from internal node x to an external node must be no greater than
log2(w(x)+1).
(B) The height of the subtree with root x must be no greater than log2(w(x)+1).
(C) Removing minimum of an n-element min HBLT is done in time O(log n).
(D) Melding two n-element min HBLTs is done in time 0(log n).
登入後即可作答並保存紀錄。
核心觀念
本題考驗**高度偏向左傾樹(Height-Biased Leftist Tree, HBLT)**的定義、結構性質以及核心操作的時間複雜度。
-
的定義(Shortest distance / 最右路徑長度):
對於樹中的任意節點 ,定義 為從節點 下降至外部節點(external node,即空指標null)的最短路徑長度。- 若 為外部節點,則 。
- 若 為內部節點(internal node),則:
-
HBLT 的結構性質:
對於 HBLT 中的每一個內部節點 ,皆滿足左子樹的最短距離不小於右子樹的最短距離:
由此可導出:
這意味著從根節點 出發到達外部節點的最短路徑,必然沿著**最右路徑(rightmost path)**延伸。 -
最右路徑長度的上界定理:
若以 為根節點的子樹包含 個內部節點,則該子樹至少包含 個內部節點:
注意:此定理僅保證「最右路徑長度(即 )」不超過 ,並不保證最左路徑或樹的高度滿足對數限制。
解題方法
本題要求找出**敘述錯誤(false)**的選項。切入點如下:
- 分析結構性質(選項 A、B):
檢查對數限制 適用於何種路徑。HBLT 僅限制「最右路徑」的長度為 ;對於「最左路徑」與「樹高(Height)」,完全沒有對數上界的約束。極端情況下(如完全左偏樹),最左路徑長度與樹高均可達 。 - 分析操作複雜度(選項 C、D):
- Melding(合併):HBLT 的合併過程僅沿著兩棵樹的「最右路徑」進行比對與重組。因為最右路徑長度至多為 ,故合併兩棵大小為 的 HBLT 所需時間為 。
- Remove Min(刪除最小值):刪除根節點後,將左右兩棵子樹進行 Melding 操作。時間複雜度由 Melding 決定,亦為 。
選項分析
第 5 題5 分
- Which of the following statements are false?
(A) The function F1 below is executable (i.e., terminable) for all positive integer x.
Int F1(int x)
{
If x is even then
return x/2;
else
return F1(F1(3x+2));
}
(B) When input data are 21 and 12, the output of function F2 below is 4.
Int F2(int x, int y)
{
If y=0 then
return x;
else
return(y, x mod y);
}
(C) Consider the function F3 below. F3(5) is 5.
Int F3(int x)
{
Int p, q;
}
If x <= 2 then
return x;
else
p=F3(x-2);
q=F3(x-3);
return p+q;
(D) None of above.
登入後即可作答並保存紀錄。
核心觀念
本題考驗**遞迴函式(Recursive Functions)**的追蹤、收斂性(Terminability)分析,以及基本數論與演算法觀念。具體包含以下三大重點:
- 遞迴終止性與不變量(Parity Invariant)分析:判斷遞迴呼叫是否具備正確的基底條件(Base Case)以及參數傳遞能否在有限步內收斂至終止條件。
- 歐幾里得演算法(Euclidean Algorithm / 輾轉相除法)與程式語法細節:理解最大公因數(GCD)遞迴求法,並注意虛擬碼或 C 語言中逗號運算子(Comma Operator)與遞迴呼叫的差異。
- 遞迴樹追蹤與動態規劃思想:利用樹狀展開或自底向上(Bottom-up)的表格繪製,精確計算遞迴函式的數值輸出。
解題方法
1. 函式 之終止性推導
給定遞迴函式:
int F1(int x) {
if (x % 2 == 0)
return x / 2;
else
return F1(F1(3 * x + 2));
}
- 分析輸入 為奇數的情況:
若 為正奇數,可將 表示為 (其中 為整數)。
代入內層表達式 :
因為 為整數,故 必定亦為奇數。 - 無窮遞迴展開:
當 為奇數時, 會優先評估內層呼叫 。由於 仍為奇數,評估 又會再度觸發更內層的呼叫 。此過程中傳入內層函式的參數永遠維持為奇數,永遠無法到達x is even(傳入偶數)的終止條件。因此對於任何正奇數 ,內層遞迴呼叫皆無法終止,導致程式進入無窮遞迴(Infinite Recursion)與堆疊溢位(Stack Overflow)。
2. 函式 之數值追蹤
給定函式:
int F2(int x, int y) {
if (y == 0)
return x;
else
return (y, x % y);
}
- 情況 A:依字面 C/C++ 逗號運算子語法
在 C 語言中,(y, x % y)屬於逗號運算子(Comma Operator),會先評估左側 ,再評估右側 ,最終返回右側表達式的值。
當 時,因 ,執行return (12, 21 % 12)。
,故函式直接回傳 。 - 情況 B:若為印製印漏函式名之輾轉相除法
return F2(y, x % y);
若補回遞迴呼叫 ,此即經典求最大公因數 的歐幾里得演算法:
第 6 題
- We have a 2-dimension integer array arr[5][5],
Which of the followings are equal to arr[2][3]?
(A) *(arr+13)
(B) ((arr+2))[3]
(C) (((arr+2))+3)
(D) (*arr+2)[3]
登入後即可作答並保存紀錄。
核心觀念
本題考驗 C / C++ 語言中二維陣列(2D Array)與指標(Pointer)的轉換語法與指標運算(Pointer Arithmetic)。
在 C / C++ 規範中,二維陣列 int arr[M][N] 在記憶體中是以**列為主順序(Row-Major Order)**連續存放。陣列名稱、指標與下標運算子 [] 之間存在以下基本轉換公式:
-
下標運算子與指標解參考(Dereference)等價公式:
因此,對於二維陣列元素arr[i][j],標準指標展開式為:
-
一維記憶體連續定址(Flattening)公式:
陣列名稱arr降級(Decay)後的*arr代表指向第一個元素arr[0][0]的指標(型態為int*)。
第 列第 行的元素arr[i][j]在連續記憶體中的一維偏移量(Offset)為 個元素空間,其等價指標表示法為:
解題方法
已知二維陣列宣告為 int arr[5][5](列數 ,行數 ),目標為找出與 arr[2][3] 等價的表達式(即列索引 、行索引 )。
-
套用二維指標標準展開:
將 代入二維指標公式 :
-
套用一維記憶體偏移量計算:
陣列每列長度 。計算 的一維連續記憶體偏移量:
將偏移量代入一維指標公式 :
選項分析
- (A)
*(*arr+13):正確。arr型態為int[5][5],在表達式中降級為指向列陣列的指標(型態為int (*)[5])。*arr解參考得到第一列開頭,進一步降級為指向第一個整數arr[0][0]的指標(型態為int*)。
第 7 題
- Given two devices, A and B, connected through a black box. When device A transmits 5 messages, ml,
m2, m3, m4, and m5, to device B sequentially, which of the following statements are false?
(A) The black box must be a queue when device B receives m1, m2, m3, m4, and m5 sequentially.
(B) The black box could be a stack when device B receives m3, m2, m1, m4, and m5 sequentially.
(C) The black box could be a max heap when device B receives m3, m2, m5, m4, and m1 sequentially.
(D) The black box neither a stack nor queue when device B receives m3, m2, ml, m4, and m5
sequentially
登入後即可作答並保存紀錄。
核心觀念
本題考驗常見抽象資料型態(Abstract Data Types, ADT)的運作特性及其輸出序列的可行性分析,涵蓋以下核心概念:
- 佇列(Queue):遵循「先進先出」(First-In, First-Out, FIFO)原則。若元素入隊順序為 ,其出隊順序必然為 。
- 堆疊(Stack):遵循「後進先出」(Last-In, First-Out, LIFO)原則。透過交錯執行進棧(Push)與出棧(Pop)操作,可產生多種有效的堆疊排列(Stack Permutation)。
- 最大堆積(Max Heap):屬於優先佇列(Priority Queue)的一種實現方式,每次取出的元素皆為目前堆積中優先權(鍵值 Key)最大者。若適當設定元素的鍵值,並配合交錯的插入(Insert)與取出最大值(Extract-Max)操作,可靈活調整輸出順序。
解題方法
裝置 A 依序傳送訊息 至黑盒子中。要判斷黑盒子是否可能為特定資料結構,需檢查是否存在一組合法的操作序列(包含進步時機與取出時機),使得裝置 B 接收到的輸出順序成立。
- 佇列輸出判斷:純佇列在無優先權參與的情況下,僅能產生唯一的 FIFO 序列 。但若輸出序列為 FIFO,黑盒子並不「必然」為佇列,因為其他結構(如堆疊)在特定操作下亦能產生相同的輸出。
- 堆疊輸出判斷:針對目標輸出序列,驗證是否符合 Stack 操作規範(元素入棧順序固定的前提下,已 Push 的元素若未 Pop,其相對順序必須滿足 LIFO 限制)。
- 最大堆積輸出判斷:為各訊息賦予合適的鍵值 ,驗證每次取出元素時,該元素是否為當時堆積內鍵值最高者。
選項分析
-
(A) 錯誤(為本題應選答案)
當裝置 B 依序收到 時,黑盒子不一定必須是佇列(Queue)。
若黑盒子為堆疊(Stack),只需對每個訊息採取「進棧後立即出棧」的操作流程:
此時堆疊同樣能輸出 序列。因此敘述中稱「黑盒子**必然(must)**為佇列」係屬錯誤。 -
(B) 正確
當裝置 B 依序收到 時,黑盒子可以是一個堆疊(Stack)。
具體操作順序如下:
第 8 題
- Given an empty hash Table T of size 17 and a set {23, 12, 34, 46, 28, 11, 6, 7, 0, 33, 13, 45} to hash into
the table. Suppose that the hash function h(k, i) = (h(k) + i) mod 17, where i = 0 to 16. After deleting 46
from the hash table, which keys should modify their positions?
(A) 11
(B) 0
(C) 33
(D) 45
(E) 13
登入後即可作答並保存紀錄。
核心觀念
-
雜湊表與開放定址法(Open Addressing - Linear Probing):
- 當發生碰撞(Collision)時,線性探測(Linear Probing)依照探測函數 依次向後尋找下一個空槽位放置。
- 本題未特別指明主雜湊函數(Primary Hash Function)時,預設使用標準的餘數法:。
-
線性探測的刪除機制(Deletion with Shift / Rehashing):
- 當從雜湊表中刪除鍵值 且不採用墓碑(Tombstone / Lazy Deletion)標記時,該槽位會留下一道「空隙(Gap)」。
- 為維護後續搜尋路徑的正確性,必須對後續連續的同集區(Cluster)元素進行位移重置。
- 對於空隙後的每一個元素,若該空隙部位落於該元素的探測路徑(即主雜湊值 至當前槽位)上,該元素即可向前移入空隙,並將釋出的新空隙繼續交由後續元素檢視,直到遇見原本即為空的槽位為止。
解題方法與推導步驟
步驟一:建構初始雜湊表
雜湊表大小 ,槽位索引為 。
依序將集合 插入雜湊表:
- :。槽位 6 為空,放入 23。
- :。槽位 12 為空,放入 12。
- :。槽位 0 為空,放入 34。
- :(與 12 碰撞)。
- 。槽位 13 為空,放入 46。
- :。槽位 11 為空,放入 28。
- :(與 28 碰撞)。
- (佔用);(佔用);(空)。放入 11 於槽位 14。
- :(與 23 碰撞)。
- 。槽位 7 為空,放入 6。
- :(與 6 碰撞)。
- 。槽位 8 為空,放入 7。
- :(與 34 碰撞)。
- 。槽位 1 為空,放入 0。
- :。槽位 16 為空,放入 33。
- :(與 46 碰撞)。
- (佔用);(空)。放入 13 於槽位 15。
- :(與 28 碰撞)。
- 探測路徑:(空)。放入 45 於槽位 2。
第 9 題
- The pseudo code below aims to reverse a linked list.
struct Node {
int data;
struct Node* next;
};
typedef struct Node* NPtr;
int main()
{
NPtr head = NULL; /* Start with an empty linked list /
push(&head, ...); / insert items into the linked list /
reverse(&head); / reverse the linked list /
}
void reverse(NPtr Href)
{
NPtr P = NULL;
NPtr C = Href;
NPtr N = NULL;
while ((1)
){
N = C->next;
C->next = (2)
P = C;
C = N;
}
(3)
}
Which of the following statements are true?
(A) Blank (1) should be C != NULL.
(B) Blank (2) should be N.
(C) Blank (3) should be *Href = C;
(D) Statement P = C; moves the pointer to the next.
登入後即可作答並保存紀錄。
核心觀念
本題考查單向鏈結串列(Singly Linked List)的迭代反轉演算法(Iterative Reversal Algorithm),屬於經典的三指標追蹤法(Three-Pointer Approach)。
演算法主要維護三個關鍵指標變數:
P(Previous):指向當前處理節點的前一個節點,初始值為NULL。C(Current):指向當前正在處理的節點,初始值為*Href(即原串列的頭指標head)。N(Next):用於暫存當前節點的原下一個節點,防止指標轉向後遺失後續串列的位址,初始值為NULL。
此外,參數 NPtr* Href 為指向頭指標的雙重指標(Pointer to Pointer),允許函式在結束前直接修改主程式中的 head 指標值。
解題方法
要實現單向鏈結串列的原地反轉(In-place Reversal),需要在走訪串列的過程中逐一將節點的 next 指向其前一個節點。
完整推導步驟如下:
-
確定迴圈終止條件——空格 (1):
迴圈需持續執行至走訪完所有節點為止。當C尚未抵達串列末端(即C != NULL)時繼續執行;當C == NULL時表示所有節點的指標皆已完成轉向。
因此,空格 (1) 應填入:C != NULL -
進行指標反轉——空格 (2):
在將N暫存為C->next後,需將當前節點C的next指標改指向前一個節點P,即執行C->next = P;。
因此,空格 (2) 應填入:P -
推進指標進行下一次疊代:
P = C;:將P移動到當前節點C的位置,作為下一個節點的前置節點。C = N;:將C移動到剛才暫存的下一個節點N。
-
更新頭指標——空格 (3):
當while迴圈結束時,C的值為NULL,而P正好指向原串列的最後一個節點(即反轉後新串列的頭節點)。因此,必須將新頭節點位址賦值給*Href,即*Href = P;。
因此,空格 (3) 應填入:*Href = P;
完整 C 語言實作程式碼
第 10 題
- The adjacency list below is for an AOE network. The end field points to a list of adjacent vertices, dur
field is the duration of the activity, link field points to another adjacent vertex, vertex field is the id of the
adjacent vertex, count field is the number of immediate predecessors. Which of the following statements
are true?
(A) The total duration of the critical path is 17.
(B) Path 0, 1, 4, 6, 8 is not a critical path.
(C) Count fields from vertex 0 to vertex 8 should be 0, 1, 1, 1, 2, 2, 1, 2, 2.
(D) The latest time that event 4 (i.e., vertex 4) can occur is 7.
🖼️【此處有附圖,請對照原卷】
登入後即可作答並保存紀錄。
核心觀念
AOE 網路以頂點表示事件、以有向邊表示活動,邊上的數字是活動所需時間。count 欄位表示該頂點的直接前驅數,也就是入度;關鍵路徑則是起點到終點之間總工期最長的路徑。
事件最早發生時間以所有前驅路徑中的最大值計算;事件最晚發生時間則由終點往回,以所有後續活動允許時間中的最小值計算:
其中 是活動 的時間。
解題方法
由圖可讀出起點為頂點 、終點為頂點 ,各頂點的鄰接資料(「相鄰頂點,活動時間」)為:
逐一計算各頂點的直接前驅數,得到 count 序列:
例如,頂點 有頂點 兩個前驅;頂點 只有頂點 一個前驅。
由起點往後計算最早發生時間:
第 11 題5 分
- Choose the correct statement(s):
(A) The insertion sort algorithm has the worst-case time complexity O(n²), the average-case time complexity O(n²),
and the best-case time complexity O(n).
(B) The merge sort algorithm has the worst-case time complexity O(n log n), the average-case time complexity
O(n log n), the best-case time complexity O(n log n), and the space complexity O(n).
(C) The quick sort algorithm has the worst-case time complexity O(n log n), the average-case time complexity
O(n log n), and the best-case time complexity O(n log n).
(D) The heap sort algorithm has the worst-case time complexity O(n log n), the average-case time complexity
O(n log n), the best-case time complexity O(n log n), and the space complexity O(n).
(E) The bubble sort algorithm has the worst-case time complexity O(n²), the average-case time complexity O(n²),
and the space complexity O(1).
登入後即可作答並保存紀錄。
核心觀念
本題考查經典**比較排序演算法(Comparison-based Sorting Algorithms)**的時間複雜度(最佳、平均、最壞狀況)與額外空間複雜度(Space Complexity / Auxiliary Space)。考生的核心任務為精確掌握以下五種排序演算法的性能指標:
- 插入排序法(Insertion Sort)
- 合併排序法(Merge Sort)
- 快速排序法(Quick Sort)
- 堆積排序法(Heap Sort)
- 氣泡排序法(Bubble Sort)
解題方法
比較排序演算法的各項複雜度與特性整理如下表:
| 排序演算法 | 最佳時間複雜度 | 平均時間複雜度 | 最壞時間複雜度 | 額外空間複雜度 | 穩定度 |
|---|---|---|---|---|---|
| Insertion Sort | 穩定 | ||||
| Merge Sort | 穩定 | ||||
| Quick Sort | 不穩定 | ||||
| Heap Sort | 不穩定 | ||||
| Bubble Sort | (具FLAG優化) | 穩定 |
根據此對照表即可精準分析各選項。
選項分析
-
(A) 正確
- 時間複雜度分析:
- 最佳狀況(Best Case):當輸入陣列已呈升冪排序時,每次插入新元素只需比較 次即可確認位置,總比較次數為 次,時間複雜度為 。
- 最壞狀況(Worst Case):當輸入陣列呈降冪(逆序)排序時,第 個元素需與前方 個元素逐一比較並後移,總比較次數為 ,時間複雜度為 。
- 平均狀況(Average Case):平均而言,第 個元素需向前移動 次,總時間複雜度為 。
- 故本選項敘述完全正確。
- 時間複雜度分析:
-
(B) 正確
- 時間複雜度分析:
- Merge Sort 採用分治法(Divide and Conquer),其遞迴關係式為 。
- 時間複雜度分析:
第 12 題
- Choose the correct statement(s):
(A) It has been proved that there exists no deterministic algorithm that can solve any given NPC problem with a
polynomial time complexity in the worst case.
(B) If we can prove that the worst-case problem lower bound of an NPC problem is of a polynomial order, then we
can prove that NP≠P.
(C) If we can prove that an existing NP-hard problem is polynomially reducible to a problem X, then X is NP-hard.
(D) If a problem is proved to be an NP-hard and NP problem, then it is an NPC problem.
(E) If a problem X can be solved by a non-deterministic algorithm taking a polynomial time complexity in the worst
case, then X is an NP problem.
登入後即可作答並保存紀錄。
核心觀念
本題考查計算複雜度理論(Complexity Theory)中關於 、、 與 (NPC) 的經典定義、多項式時間規約(Polynomial-time Reduction)的傳遞性,以及經典未解問題 的概念。
- 類別(Polynomial Time):可由「確定性演算法」(Deterministic Algorithm)在最壞情況下以多項式時間 求解的判定問題集合。
- 類別(Nondeterministic Polynomial Time):可由「非確定性演算法」(Non-deterministic Algorithm)在最壞情況下以多項式時間 求解(或可在多項式時間內驗證其解)的判定問題集合。
- 類別:若對所有 ,均滿足 ( 可多項式時間規約至 ),則稱問題 為 。注意 問題本身不一定要屬於 。
- (NPC) 類別:問題 若同時滿足以下兩個條件,則定義為 NPC 問題:
- (1)
- (2)
- 多項式時間規約()之傳遞性:若 且 ,則 。
解題方法
依據複雜度類別的嚴格數學定義與計算理論公式進行判斷:
- 未解問題的判定:目前學界尚未證明 或 ,凡聲稱「已證明(proved)」無多項式時間確定性演算法可解 NPC 問題的敘述皆不成立。
- 規約方向與歸屬判定:
- 欲證明 為 ,必須將「已知為 的問題 」規約至 (即 )。
- 欲證明 為 ,必須同時滿足 與 。
- 的基本定義:直接根據非確定性演算法於多項式時間內可求解進行歸屬認定。
選項分析
- (A) 錯誤。
至今計算機科學界尚未證明是否存在確定性多項式時間演算法可以解決 NPC 問題(即著名的 開放問題)。雖然理論學界普遍猜測 ,但該結論至今尚未被數學證明。
第 1 題9 分
- Given a weighted connected undirected graph G=(V, E) with node set V and edge set E, a subgraph M of G is
called a spanning tree of G if M = (V, T), T ⊆ E, and |T|=|V|−1. M is called a minimal spanning tree (MST) of G if
M is a spanning tree of G with the minimal total weight. Below is the Prim's MST algorithm to output the MST of
a given graph G.
Algorithm: Prim's MST algorithm
Input: A weighted connected undirected graph G=(V, E), where |V|=n
Output: The MST M=(V, T) with the minimal total weight, where |T|=n-1
1: T←φ
2: X← {w}, where w is an arbitrary node in V
3: while |T| < n-1 do
4: select an edge (u, v)∈E with the minimal weight such that u∈X and v∈(V-X)
5: T←T∪{(u, v)}
6: X←X∪{v}
7: return M=(V, T)
Please follow the form of the Prim's MST algorithm to
(1) write the well-known Kruskal's MST algorithm (9%) and
(2) analyze the worst-case time complexity of the Kruskal's MST algorithm (6%).
Note that you should strictly follow the form of the Prim's MST algorithm to write the Kruskal's MST algorithm;
otherwise, you will lose some points.
登入後即可作答並保存紀錄。
核心觀念
本題考查兩種最小生成樹(Minimum Spanning Tree, MST)演算法:
- Prim 演算法:從一個頂點開始,逐步加入連接目前頂點集合與外部頂點集合的最小權重邊。
- Kruskal 演算法:按照邊的權重由小到大考慮,若加入該邊不會形成環,就將其加入生成樹。
設圖中:
- :頂點數
- :邊數
生成樹必須滿足:
Kruskal 演算法的核心判斷是:
若邊 的兩端點目前位於不同連通元件,加入此邊不會形成環;若兩端點位於同一連通元件,加入此邊會形成環。
此判斷通常使用 Disjoint Set Union(DSU,互斥集合)完成,並搭配 find 與 union 操作。
解題方法
Kruskal 演算法先將所有邊依權重遞增排序,再依序處理每一條邊:
- 初始時每個頂點各自形成一棵樹。
- 每次選擇尚未處理且權重最小的邊 。
- 若 、 屬於不同的樹,加入該邊並合併兩棵樹。
- 若 、 已在同一棵樹,捨棄該邊,以避免形成環。
- 當選出的邊數達到 時停止。
這與 Prim 演算法的輸出格式一致,皆以 儲存答案,最後輸出 。
Kruskal's MST Algorithm
Algorithm: Kruskal's MST algorithm
Input:
A weighted connected undirected graph G=(V, E),
where |V|=n
Output:
The MST M=(V, T) with the minimal total weight,
where |T|=n-1
1: T ← φ
2: F ← {{v} | v∈V}
3: sort all edges in E in nondecreasing order of weight
4: while |T| < n-1 do
5: select an edge (u, v)∈E with the minimal weight
among the unselected edges
such that u and v belong to different trees in F
6: T ← T∪{(u, v)}
7: merge the two trees containing u and v in F
8: return M=(V, T)
其中第 5 行可使用 DSU 實作:
if find(u) ≠ find(v) then
T ← T∪{(u, v)}
union(u, v)
第 2 題13 分
- (13%) You are going on a long hiking trip. You start on the road at kilometer post 0. Along the way there are n
hotels, at kilometer posts a1 < a2 < ... < an, where each a; is measured from the starting point. The only places you
are allowed to stop are at these hotels, but you can choose which of the hotels you stop at. You must stop at the
final hotel (at distance an), which is your destination. You'd ideally like to travel 20 kilometers a day, but this may
not be possible. If you travel x kilometers during a day, the penalty for that day is (20 – x)². You want to plan your
trip so as to minimize the total penalty. Give an algorithm that determines the optimal sequence of hotels at which
to stop. (Note: This problem can be solved by a dynamic programming algorithm. If you use a dynamic
programming algorithm to solve this problem, please write down the recursive formula of the algorithm, describe
the meaning of the notations you used in the formula, give the initial value settings, and analyze the time
complexity of the algorithm.)
登入後即可作答並保存紀錄。
核心觀念
本題屬於經典的**動態規劃(Dynamic Programming, DP)**問題,源自 Introduction to Algorithms (CLRS) 演算法經典範例。
解答本題需要掌握以下核心觀念與定義:
- 最佳子結構(Optimal Substructure):若到達第 個旅館的最佳路線是在第 個旅館停靠(其中 ),則從起點到第 個旅館的路線也必定是到達第 個旅館的最佳路線。
- 重疊子問題(Overlapping Subproblems):計算到達後續旅館的最佳代價時,會重複用到先前已計算好的較小規模子問題的解答(即到達前幾個旅館的最小懲罰值)。
- 路徑重建(Path Reconstruction):題目除了要求計算最小懲罰值外,還要求輸出最佳旅館停靠序列(optimal sequence of hotels),因此必須維護一個追蹤陣列(
parent或prev),以便完成 DP 表格後進行回溯(Backtracking)。
解題方法
1. 符號定義 (Notations)
- 令 表示出發起點(公里數為 )。
- 令 表示沿途 間旅館的位置(單位:公里),滿足 。
- :表示從起點 出發,並以第 間旅館作為當天住宿點時,到達第 間旅館所產生的最小總懲罰值(Minimum Total Penalty)。
- :記錄使得 達到最小值的上一個停靠點索引 (用於追蹤並重建最佳停靠序列)。
2. 遞迴式 (Recursive Formula)
到達第 間旅館的上一站可以是起點 或先前的任意旅館 (其中 )。當天天行進距離為 公里,當天懲罰值為 。
因此,狀態轉移方程式如下:
同時,對應的最佳前驅結點記錄為:
3. 初始值設定 (Initial Values)
- :位於起點 時,累積懲罰值為 。
- :將其餘狀態初始化為無窮大。
- :前驅站索引初始化為 。
4. 演算法邏輯與虛擬碼 (Algorithm & Pseudocode)
第 3 題12 分
- (12%) For a set of variables x1, x2, ..., Xn, you are given some equality constraints, of the form "x₁ = x;" and some
disequality constraints, of the form "x; ≠ xj". Is it possible to satisfy all of them? For instance, the constraints :
X1=X2,; X2 = X3; X3 = X4; X1 ≠ X4;
cannot be satisfied. Give an efficient algorithm that takes as input m constraints over n variables and decides
whether the constraints can be satisfied. Describe the data structure used by your algorithm, and analysis the time
complexity of your algorithm.
登入後即可作答並保存紀錄。
核心觀念
本題考查的核心觀念為**等價關係(Equivalence Relation)與互斥集資料結構(Disjoint-Set Union / Union-Find)**的應用。
- 等價關係與遞移性:
等號 Constraints()滿足自反性、對稱性與遞移性(Transitivity)。因此,一連串的等式約束會將變數集合劃分為數個互不相交的「等價類(Equivalence Classes)」或「連通分量(Connected Components)」。在同一個等價類中的所有變數,其賦值必須完全相同。 - 矛盾判斷邏輯:
對於任意不等式 Constraints(),若變數 與 在等式遞移推導後屬於「同一個等價類」,則產生無法滿足的邏輯矛盾;反之,若所有不等式約束所涉及的兩變數均屬於「不同等價類」,則必定能找到一組實數(或整數)賦值滿足所有條件。 - 互斥集資料結構(Disjoint-Set / Union-Find):
為了高效動態維護這些變數的等價類關係,需使用 Union-Find 資料結構,並搭配**路徑壓縮(Path Compression)與按秩合併(Union by Rank / Size)**兩大優化技術,以達到近乎線性的執行時間。
解題方法
1. 資料結構設計
採用 Disjoint-Set (Union-Find) 維護 個變數的連通狀態:
parent[1..n]:整數陣列,parent[i]記錄變數 所屬樹狀結構中的父節點。若parent[i] == i,代表 為該集合的根節點(代表元素)。rank[1..n]:整數陣列,記錄以 為根的樹高上限(或子集大小),用於合併時維持樹平衡。
支援以下核心操作:
Make-Set(i):初始化變數 ,令parent[i] = i且rank[i] = 0。Find-Set(i):尋找 所屬集合的根節點,並在搜尋過程中執行路徑壓縮(將沿途經過的節點直接指向根節點)。Union(i, j):將 與 所在的集合合併。使用按秩合併,將秩(Rank)較小的樹掛載至秩較大的樹之下。
2. 演算法步驟與邏輯
本演算法採用兩階段處理原則(Two-Pass Approach):
-
階段一:合併所有等式(Equality Constraints)
- 初始化包含 個變數的 Union-Find 資料結構。
- 遍歷所有形式為 "" 的等式 constraints。
- 對於每一組等式,呼叫
Union(i, j),將變數 與 歸納至同一個等價類中。
-
階段二:檢查所有不等式(Disequality Constraints)
- 遍歷所有形式為 "" 的不等式 constraints。
- 對於每一組不等式,查詢
Find-Set(i)與Find-Set(j):- 若
Find-Set(i) == Find-Set(j):表示 與 已被等式約束推導為必須相等,但此處又要求兩者不相等,發生矛盾,演算法立即回傳False(不可滿足)。
- 若
- 若遍歷完所有不等式皆未發現矛盾,則回傳
True(可滿足)。