112 年 國立臺灣聯合大學系統(清華、政治、陽明交通、中央四校聯招)研究所電機類《資料結構》
第 1 題3 分
Let Fibonacci(0)=0, Fibonacci(1)=1, Fibonacci(2)=1, Fibonacci(3)=2, Fibonacci(4)=3, and Fibonacci(i+2)=Fibonacci(i)+Fibonacci(i+1), what is Fibonacci(8) equal to?
(A) 34
(B) 21
(C) 8
(D) 13
登入後即可作答並保存紀錄。
核心觀念
本題測試的是「費波那契數列的遞迴定義」與「由定義逐步推導出第 項的能力」。掌握遞迴關係 ,即可以簡單的迭代方式依序求出目標值。
解題過程
- 確認已給出的前幾項
-
套用遞迴公式
依題目遞迴式 ,從已知的 開始往後算:- 時
- 時
第 2 題3 分
If we insert a number 13 to a max-heap [16, 14, 10, 8, 7, 9, 3, 2, 4, 1] at the end of the array structure [16, 14, 10, 8, 7, 9, 3, 2, 4, 1, 13] and run the necessary procedure to maintain the max-heap property, what is the new structure after the max-heap property is restored?
(A) [16, 14, 10, 8, 7, 9, 3, 2, 4, 1, 13]
(B) [16, 14, 10, 8, 7, 9, 13, 2, 4, 1, 3]
(C) [16, 14, 10, 8, 13, 9, 3, 2, 4, 1, 7]
(D) [16, 14, 10, 13, 7, 9, 3, 2, 4, 1, 8]
登入後即可作答並保存紀錄。
核心觀念
本題考查最大堆積(max-heap)的插入與上濾(heapify-up)操作。
最大堆積必須符合:
以陣列儲存堆積時,若採用從 開始的索引:
- 父節點索引:
- 左子節點索引:
- 右子節點索引:
插入新元素時,先將元素放在陣列最後,再依序與父節點比較;若新元素較大,就向上交換,直到恢復最大堆積性質。
解題方法
原最大堆積為:
將 放到陣列最後:
新元素 位於索引 ,其父節點索引為:
索引 的元素為 。因為:
因此交換 與 :
此時 位於索引 ,其父節點索引為:
第 3 題3 分
Given the following pseudo code of Quicksort algorithm, which statement is true?
(A) The output of Quicksort() is a non-increasing sorted sequence.
(B) The Quicksort() is a stable sorting algorithm
(C) The worst time performance for the Quicksort() is O(n²)
(D) None of the above
Quicksort(A,p,r)
1 if p<r
2 q=Partition(A,p,r)
3 Quicksort(A,p,q-1)
4 Quicksort(A,q+1,r)
Partition(A,p,r)
1 x = A[r]
2 i = p-1
3 for j = p to r-1
4 if A[j] <= x
5 i=i+1
6 exchange A[i] with A[j]
7 exchange A[i+1] with A[r]
8 print(A[p:r])
9 return i+1
登入後即可作答並保存紀錄。
核心觀念
本題考查 Quicksort 的:
- Partition 分割方式與排序方向
- 穩定排序(stable sort)的定義
- 最差時間複雜度分析
此程式選取最後一個元素 作為 pivot,並將所有小於等於 pivot 的元素移到左側,因此完成分割後:
其中 是 pivot 最終所在的位置。遞迴處理左右兩個子陣列後,整體結果為非遞減排序。
解題方法
判斷各選項是否符合此 Quicksort 的性質:
- 觀察 Partition 使用的比較運算,判斷排序方向。
- 檢查交換操作是否保證相等元素的相對順序。
- 分析 pivot 每次都落在極端位置時的遞迴時間。
當輸入已接近排序完成,且每次選到的 pivot 都是最小值或最大值時,分割結果會極度不平衡:
因此:
選項分析
(A) The output of Quicksort() is a non-increasing sorted sequence.
錯誤。
程式在第 4 行使用:
if A[j] <= x
小於等於 pivot 的元素被放到左側,大於 pivot 的元素位於右側,所以結果是非遞減排序:
第 4 題
According to the pseudo code given in question 3, which of the following is NOT a possible print out result by Line 8 print(A[p:r]) in Partition(A,p,r)?
(A) 11, 12, 19, 6, 13
(B) 11, 12, 6, 13, 19
(C) 6, 11,12, 13, 19
(D) 11, 6, 12, 19, 13
登入後即可作答並保存紀錄。
在 Partition 的 Lomuto 實作中,最後一次交換會把基準值 放到最終位置 。
於第 8 行列印的子陣列 (含基準值)必須滿足:
- 所有 的元素出現在基準值左側,
- 所有 的元素出現在基準值右側。
以題目給出的元素集合 而 為最後的 ,唯一會違反上述順序的是把 (唯一大於 的元素)置於任何小於等於 的元素之前。
第 5 題
The following pseudo code is a simple algorithm to generate a permutation of n items. Please fill in the underscored area in Line 6 with a correct formula such that i <= j < n
1 function Uniform(m)
2 return a random integer between 0 and m-1; // uniform distribution
3
4 function Permutation(A,n)
5 for i = 0 to n-2 // 0-based indexing system
6 j = i + Uniform(______); // j is a random integer. i<=j<n
7 swap(A[i], A[j]);
登入後即可作答並保存紀錄。
核心觀念
本題考查以均勻分布產生隨機排列(uniform random permutation),以及陣列索引範圍的推導。
在第 次迴圈中,題目要求:
程式設定:
其中 Uniform(m) 會均勻產生:
解題方法
為使 的可能範圍涵蓋 到 ,令:
則:
因此:
其範圍為:
- 最小值:
- 最大值:
完全符合 ,且每個合法索引都有相同機率被選到。
關鍵程式碼
第 6 題
Run the function Permutation(A,n) given in question 5 with A=[1,2,3,4,5,6], n=6 and the randomization results: i=0, j =4; i=1, j =3; i=2, j =2; i=3, j =5; i=4, j =5. What is the resultant permuted A?
(A) [5,4,3,6,2,1]
(B) [4,2,6,5,3,1]
(C) [2,5,4,6,1,3]
(D) [4,6,2,5,3,1]
登入後即可作答並保存紀錄。
核心觀念
本題考查陣列的隨機排列(random permutation),採用 Fisher–Yates shuffle 的交換方式:
for i = 0 to n-2
j = 隨機選取的索引,且 i ≤ j < n
swap(A[i], A[j])
每一輪固定目前位置 ,再將 與指定位置 交換。
解題方法
初始陣列為:
依序套用題目給定的 :
| 步驟 | 交換內容 | 陣列結果 |
|---|---|---|
| 初始 | — | |
| 交換 與 | ||
| 交換 與 | ||
| 自己與自己交換 | ||
| 交換 與 |
第 7 題3 分
What is the time complexity of pushing a new element onto a stack with n elements using an array-based implementation?
(A) O(1)
(B) O(n)
(C) O(n²)
(D) O(log n)
登入後即可作答並保存紀錄。
核心觀念
本題考查以陣列實作堆疊(stack)時,push 操作的時間複雜度。
堆疊遵守「後進先出」(LIFO, Last In First Out),新增元素時一律放在堆疊頂端。陣列式堆疊通常以變數 top 記錄目前頂端位置,因此新增元素只需:
- 將元素放入
top的下一個位置。 - 更新
top。
這些操作都只執行固定次數,與堆疊中元素數量 無關。
解題方法
假設陣列尚有可用空間,push 的概念程式碼如下:
push(x):
top = top + 1
stack[top] = x
每個步驟皆為固定時間:
因此,將新元素推入具有 個元素的陣列式堆疊,時間複雜度為:
選項分析
- (A) :正確
第 8 題3 分
Consider the given graph, what is the weight of the minimum spanning tree using the Prim's algorithm, starting from vertex a?
🖼️【此處有附圖,請對照原卷】
(A) 23
(B) 28
(C) 27
(D) 11
登入後即可作答並保存紀錄。
核心觀念
最小生成樹會連接圖中的所有頂點,且不形成環;若圖有 個頂點,生成樹恰有 條邊。Prim 演算法從指定頂點開始,每一步都選擇「已加入頂點集合」與「尚未加入頂點」之間權重最小的邊。
解題方法
從頂點 開始。圖中的邊權重為:、、、、。
- 目前只有 ,可選邊中最小的是 ,權重為 。
- 已加入 ,連往未加入頂點的邊中,最小權重為 。可選 或 ,兩者同權。
- 加入其中一條權重 的邊後,剩下的頂點可用 連接,權重為 。
因此最小生成樹的總權重為
第 9 題3 分
Let G be a complete graph with 4 vertices. How many spanning trees does graph G have?
(A)12
(B)8
(C)16
(D)25
登入後即可作答並保存紀錄。
核心觀念
完全圖 是任意兩個不同頂點之間皆有一條邊的圖。
生成樹(spanning tree)必須同時符合:
- 包含原圖的全部頂點;
- 連通;
- 不含任何 cycle;
- 若有 個頂點,必定有 條邊。
本題的圖為完全圖 ,可使用凱萊公式(Cayley’s formula):
解題方法
令 ,代入凱萊公式:
因此,具有 個頂點的完全圖共有 棵生成樹。
選項分析
第 10 題3 分
Given the following code, what will happen during the execution?
1 void do_job()
2 {
3 do_job();
4 }
5 int main()
6 {
7 do_job;
8 return 0;
9 }
(A) The code cannot be compiled
(B) The code will be executed successfully and "0" will be printed out
(C) The code will be executed successfully and random output will be exported
(D) The code will be executed successfully, but an overflow will occur
登入後即可作答並保存紀錄。
核心觀念
函式名稱後面有沒有括號,會決定程式是呼叫函式,還是只提到函式本身:
do_job();會呼叫do_job。do_job;是一個沒有實際作用的運算式敘述,不會呼叫函式。
此外,return 0; 是讓 main 回傳狀態碼 ,不會把字元 0 印到螢幕上。要輸出文字,必須使用輸出函式。
解題方法
逐行檢查 main:
int main()
{
do_job;
return 0;
}
第 7 行沒有呼叫括號,因此不會進入 do_job。雖然 do_job 函式本身包含遞迴呼叫,但只有執行 do_job() 時才會開始遞迴。
第 11 題3 分
Which of the following arrays are max binary heaps?
(A) {9, 16, 3, 2, 4, 8, 5, 14, 12}
(B) {16, 9, 14, 8, 5, 12, 2, 4, 3}
(C) {16, 8, 14, 5, 2, 9, 12, 4, 3}
(D) {16, 14, 9, 4, 8, 12, 5, 3, 2}
(E) {16, 14, 9, 4, 12, 8, 5, 3, 2}
登入後即可作答並保存紀錄。
核心觀念
最大二元堆積(max binary heap)必須同時滿足:
- 結構為完全二元樹。
- 每個節點的鍵值都不小於其子節點:
以陣列採 1-based indexing 表示時:
- 第 個節點的父節點位置為:
- 左子節點位置為
- 右子節點位置為
因此,只要逐一檢查每個父節點與其子節點的大小關係即可。陣列長度皆為 ,其對應的完全二元樹如下:
a[1]
/ \
a[2] a[3]
/ \ / \
a[4] a[5] a[6] a[7]
/ \
a[8] a[9]
實際上只需檢查位置 到 的節點。
選項分析
(A)
根節點為 ,其左子節點為 :
父節點小於子節點,違反最大堆積的條件,因此不是 max binary heap。
(A)錯誤。
(B)
逐一檢查父節點:
- 位置 :
- 位置 :
- 位置 :
第 12 題3 分
Use a stack structure with only push and pop operations. An array with 4 items {A,B,C,D} is processed by push(A), push(B), push(C), push(D) sequentially with all possible legal pop() to remove the item on top of the stack at any time. For example, we can execute push(A), push(B), push(C), push(D), and then pop(), pop(), pop(), pop() to reverse the order to get D, C, B, A pop sequentially. What of the following are not possible pop sequences using a stack?
(A) ACBD
(B) CDBA
(C) CDAB
(D) BDCA
(E) BDAC
登入後即可作答並保存紀錄。
使用堆疊只能產生 stack‑sortable 的排列,等價於避免模式 。
依序模擬 push A、B、C、D 的過程:
- ACBD:A 立即 pop,接著 push B、C、pop C,再 pop B,最後 push D、pop D → 可行
- CDBA:push A、B、C,pop C → C;push D,pop D → D;此時堆疊為 A、B,依序 pop B、A → 可行
第 13 題3 分
Suppose that we have numbers between 1 and 1000 in a binary search tree and we want to search the number 101. Which of the following sequences could NOT be the sequence of nodes examined?
(A) 20, 252, 41, 49, 130, 120, 131, 101
(B) 252, 20, 41, 49, 131, 130, 120, 101
(C) 100, 200, 131, 130, 120, 110, 105, 101
(D) 80, 252, 90, 130, 120, 131, 110, 101
(E) 90, 252, 100, 131, 130, 120, 110, 101
登入後即可作答並保存紀錄。
搜尋二元搜尋樹的過程必須遵守:
- 若欲找之鍵 小於目前節點值 ,則必須往左子樹走,下一個被檢查的節點必須
- 若 ,則往右子樹走,下一個節點必須
以 為例,逐筆檢查每個序列:
| 序列 | 判斷 | 是否違背規則 |
|---|---|---|
| A 20 → 252 → 41 → 49 → 130 → 120 → 131 → 101 | 在節點 120 時 ,應往左走,卻出現 (右子節點) | 違背 |
第 14 題3 分
Which of the following data structures have constant or nearly constant data element access time O(1)?
(A) stack
(B) linked list
(C) array
(D) hash table
(E) AVL tree
登入後即可作答並保存紀錄。
核心觀念
本題考查不同資料結構的「資料元素存取時間複雜度」。
若能直接根據索引、雜湊值或固定位置取得資料,所需步驟與資料量 無關,時間複雜度為:
各資料結構的典型存取複雜度如下:
| 資料結構 | 典型存取方式 | 時間複雜度 |
|---|---|---|
| Stack | 存取頂端元素(top) | |
| Linked list | 依序尋找第 個元素 | |
| Array | 依索引直接存取 | |
| Hash table | 依 key 查找,平均情況 | |
| AVL tree | 依鍵值搜尋 |
其中,Hash table 的 是平均時間;若發生大量碰撞,最壞情況可能退化為 。
解題方法
判斷每個選項是否具有 存取時間,關鍵在於:
- 是否能直接定位資料元素。
- 是否需要從頭逐一尋找。
- 若為樹結構,搜尋高度是否會隨 增加。
能直接定位或存取固定位置者,通常為 ;必須沿著鏈結或樹的路徑尋找者,通常至少為 或 。
選項分析
(A) Stack
Stack 遵守後進先出(LIFO, Last In First Out)原則,資料的標準存取位置是頂端:
push:將元素放入頂端。pop:移除頂端元素。top或peek:查看頂端元素。
只要維護一個 top 指標,這些操作都只需固定次數的指標移動或陣列存取,因此時間複雜度為:
所以在資料結構的標準操作定義下,(A) 正確。
補充而言,若題目要求任意存取 Stack 中間的元素,則必須先移除或逐層經過上方元素,不能視為 。本題採用 Stack 的標準頂端存取定義。
(B) Linked list
Linked list 的節點通常只知道下一個節點的位置。若要取得第 個元素,必須從頭節點開始逐一走訪:
第 15 題3 分
Which of the following are legal postfix expressions?
(A) ABC*+
(B) ABC*+D+
(C) ABCD+
(D) ABC+D+E+
(E) ++A*BCD
登入後即可作答並保存紀錄。
判斷要點
- 從左至右讀取;遇到運算子時必須先有足夠的運算元在堆疊中。
- 完全讀完後堆疊只能剩一個值,才是合法的 postfix 表達式。
各選項檢驗
| 選項 | 步驟概述 | 結果 |
|---|---|---|
(A) ABC*+ | 推入 A,B,C → * 消費 B,C → + 消費 A 與 B*C | 合法 |
第 16 題3 分
Given a graph G(V,E) where vertices V={A,B,C,D,E,F} and Edges E={(A,B), (A,D), (C,A), (C,E), (C,F), (D,C), (F,D)}. Edges (A,B), (A,D), are directed from A to B, A to D, etc. Which of the following vertices form loops?
(A) ABC
(B) ABD
(C) CAD
(D) BDF
(E) DCF
登入後即可作答並保存紀錄。
先列出所有有向邊
檢查每個選項是否能形成有向環(循環):
-
ABC:需 , ,
不存在 → 不是環。 -
ABD:需 , ,
、 均不存在 → 不是環。
第 17 題3 分
Which of the following data structures are linear data structures?
(A) Stack
(B) Queue
(C) Linked list
(D) Array
(E) Binary tree
登入後即可作答並保存紀錄。
核心觀念
線性資料結構(linear data structure)是指資料元素依序排列,除了第一個與最後一個元素外,每個元素都具有唯一的前驅與唯一的後繼。其邏輯關係可表示為:
常見的線性資料結構包括:
- Array(陣列)
- Linked list(鏈結串列)
- Stack(堆疊)
- Queue(佇列)
Binary tree(二元樹)則屬於非線性資料結構,因為一個節點可能同時連接到兩個子節點,資料關係呈現階層狀,而非單一路徑。
解題方法
判斷每個選項的資料元素是否形成「單一路徑的先後關係」:
- 若每個元素最多只有一個直接前驅與一個直接後繼,屬於線性資料結構。
- 若資料具有分支、階層或一對多的關係,屬於非線性資料結構。
選項分析
(A) Stack
Stack(堆疊)是線性資料結構,遵循後進先出(Last In, First Out, LIFO)原則。
元素雖然只能從堆疊頂端加入或移除,但所有元素仍排列在單一序列中:
因此正確。
(B) Queue
Queue(佇列)是線性資料結構,遵循先進先出(First In, First Out, FIFO)原則。
元素從尾端加入、從前端移除,但資料元素仍維持單一線性順序,因此正確。
(C) Linked list
第 18 題3 分
Which of the following statements are true about singly linked lists?
(A) They use less memory than doubly linked lists
(B) They allow traversal in both directions
(C) They require less time to insert or delete elements than doubly linked lists
(D) They allow random access to elements
(E) All of the above is true
登入後即可作答並保存紀錄。
核心觀念
單向鏈結串列(singly linked list)的每個節點通常包含:
- 資料欄位
data - 指向下一個節點的指標
next
節點結構可表示為:
雙向鏈結串列(doubly linked list)則多一個指向前一個節點的指標 prev:
因此,單向鏈結串列的主要特性是:
- 每個節點只需儲存一個連結指標,記憶體使用量較少。
- 只能沿著
next指標由前往後走訪。 - 不支援以索引直接存取第 個元素。
- 插入與刪除的效率取決於是否已知適當的前置節點或位置指標,不能一概而論為比雙向鏈結串列更快。
解題方法
逐一檢查各選項是否符合單向鏈結串列的定義與操作特性:
- 比較節點需要儲存的指標數量,可判斷記憶體使用量。
- 觀察是否具有
prev指標,可判斷能否反向走訪。 - 比較插入、刪除時尋找前置節點的成本,可判斷時間效率。
- 判斷是否能透過索引直接定位節點,可判斷是否支援隨機存取。
選項分析
(A) They use less memory than doubly linked lists
正確。
單向鏈結串列每個節點只需要一個 next 指標;雙向鏈結串列每個節點需要 prev 與 next 兩個指標。
若有 個節點,單向鏈結串列額外使用約 個指標空間,雙向鏈結串列則約使用 個指標空間。因此,單向鏈結串列通常比雙向鏈結串列節省記憶體。
其空間複雜度皆為 ,但單向鏈結串列的常數較小。
(B) They allow traversal in both directions
錯誤。
單向鏈結串列只有 next 指標,能從目前節點前往下一個節點:
節點沒有指向前一個節點的 prev 指標,因此無法直接由目前節點回到前一個節點,也不能由尾端向前走訪。
能雙向走訪是雙向鏈結串列的特性。
第 19 題3 分
Which of the following statements about hashing tables is/are true?
(A) Hashing tables use hash functions to map keys to indices in an array
(B) Hashing tables may have multiple keys that map to the same index
(C) Hashing tables have a fixed size and cannot grow or shrink
(D) Hashing tables can use linked lists to store elements with the same hash value
(E) All of the above is true
登入後即可作答並保存紀錄。
解說
- A:雜湊表使用雜湊函數把鍵映射到陣列索引 → 正確。
- B:不同鍵可能得到相同雜湊值,稱為collision → 正確。
第 20 題3 分
Which of the following statements about depth first search (DFS) are true?
(A) DFS is a searching algorithm that visits all the nodes of a graph in a depth-first manner
(B) DFS always finds the shortest path between two nodes in a graph
(C) DFS can be used to find the topological ordering of the nodes in a directed acyclic graph
(D) DFS can be used to solve the traveling salesperson problem in polynomial time
(E) All of the above is true
登入後即可作答並保存紀錄。
核心觀念
本題考查深度優先搜尋(Depth-First Search, DFS)的基本性質、應用範圍,以及與最短路徑、拓撲排序、旅行推銷員問題的關係。
DFS 的基本作法是:
- 從一個起點出發。
- 優先沿著尚未拜訪的鄰接節點深入。
- 無法繼續深入時回溯。
- 使用遞迴或堆疊記錄搜尋路徑。
若圖有 個節點、 條邊,使用鄰接串列實作時,DFS 的時間複雜度為
空間複雜度通常為
其中包含拜訪標記、遞迴堆疊或明確使用的堆疊。
解題方法
判斷本題各選項時,依序檢查:
- 是否符合 DFS 的正式定義。
- DFS 是否保證該性質。
- 該問題是否確實能由 DFS 在指定複雜度內解決。
- 全部選項都正確時,選項 E 才會成立。
DFS 的核心特徵是「盡可能深入後再回溯」,但它並不根據邊數或路徑權重尋找最短路徑,也不具備解決所有最佳化問題的多項式時間能力。
選項分析
(A) DFS is a searching algorithm that visits all the nodes of a graph in a depth-first manner
正確。
DFS 是一種圖搜尋與圖走訪演算法,會以深度優先的方式拜訪節點:先沿著目前路徑不斷深入,直到沒有未拜訪的鄰接節點,再逐層回溯。
若圖為非連通圖,從單一起點執行 DFS 只能拜訪該起點所在的連通分量;完整的圖走訪會在 DFS 結束後,從其他尚未拜訪的節點重新啟動 DFS,形成 DFS forest。因此在圖搜尋的標準定義下,DFS 能拜訪圖中的所有節點。
(B) DFS always finds the shortest path between two nodes in a graph
錯誤。
DFS 不保證找到兩個節點之間的最短路徑。它只按照某一條路徑深入到底,再進行回溯;第一次找到目標節點時,該路徑可能不是最短路徑。
例如,圖中從起點 到終點 有兩條路徑:
- ,長度為
- ,長度為
若 DFS 先探索 ,可能先找到長度為 的路徑,卻沒有找到最短路徑。
在無權圖中,保證邊數最少路徑的演算法是廣度優先搜尋(BFS);在帶有非負權重的圖中,通常使用 Dijkstra 演算法。DFS 本身沒有最短路徑保證。
第 21 題10 分
Compare Merge_sort with Insertion_sort.
(A) Which one is in-place sorting algorithm? (2 points)
(B) What is the memory cost of Merge_sort in Big-O annotation with n? (2 points)
(C) A[p:q] and A[q+1:r] are sorted sub-arrays. A[p:q] represents the sub-array from A[p] to A[q]. A[q+1:r] represents the sub-array from A[q+1] to A[r]. Write a pseudocode to describe a function Merge(A,p,q,r) which merges A[p:q] and A[q+1:r] such that the resultant A[p:r] are sorted. Assume the array is sorted from small to large numbers. (4 points)本題應詳列過程,無過程者不予計分
(D) What is the computation complexity of Merge(A,p,q,r) using the Big-O annotation with n. (2 points)
登入後即可作答並保存紀錄。
核心觀念
本題比較兩種排序法:
- Insertion Sort(插入排序):逐一取出元素,將其插入前方已排序區間。
- Merge Sort(合併排序):採用分治法,先將陣列遞迴切半排序,再利用
Merge合併兩個已排序子陣列。
相關定義:
- In-place sorting:主要在原陣列內 rearrange 元素,只使用 額外儲存空間。
- Merge Sort 的合併階段通常需要額外陣列暫存元素。
- Big-O 用來表示輸入規模增加時,時間或記憶體需求的漸近上界。
解題方法
(A) 哪一個是 in-place sorting algorithm?
Insertion Sort 將元素直接在原陣列中向右移動,再插入正確位置,只需使用少量暫存變數,因此屬於 in-place sorting algorithm。
標準 Merge Sort 在合併兩個已排序子陣列時,通常需要建立暫存陣列,將合併結果寫回原陣列,因此不屬於標準的 in-place sorting algorithm。
答案:Insertion Sort。
補充:
- Insertion Sort 額外空間:
- Merge Sort 額外空間:
題目採用一般教科書的 Merge Sort 定義;雖然存在特殊的原地合併技術,但不屬於標準實作。
(B) Merge Sort 的記憶體成本
令輸入陣列大小為 。
Merge Sort 的合併階段需要額外配置暫存陣列,最多須暫存與目前處理區間同等數量的元素,因此額外陣列需要:
遞迴呼叫堆疊深度為:
合併陣列的空間成本會主導遞迴堆疊成本,因此總記憶體成本為:
答案:。
(C) Merge(A,p,q,r) 虛擬碼
已知:
- 已由小到大排序
- 已由小到大排序
- 目標是將兩者合併,使 由小到大排序
設:
建立兩個暫存陣列:
- 儲存左半部
- 儲存右半部
接著使用兩個索引分別指向 與 尚未取出的最小元素。每次比較兩者,將較小者寫回 。
第 22 題10 分
Given the following pseudo codes, Insertion-sort2 improves the performance of Insertion-sort1 by using a binary search strategy. Please write a binary search algorithm, j=Binary-search(A,p,q,key), that returns the insertion location index j. The resultant Binary-search has to be in-place, stable, and O(log n) for arrays with repeating/duplicate numbers. For example, A = {2,3,3,3,4,5,3}, Binary-search(A,1,6,3) return 5. Answer in pseudocode or C-style code with index beginning at 1. (10%)
Insertion-sort1(A)
1 for j=2 to A.length
2 key=A[j]
3 i=j-1
4 while i>0 and A[i]>key
5 A[i+1]=A[i]
6 i=i-1
7 A[i+1]=key
Insertion-sort2(A)
1 for j=2 to A.length
2 key=A[j]
3 i=Binary-search(A,1,j-1,key) // provide code for Binary-search
4 A[i+1:j]=A[i:j-1] // move A[i:j-1] to A[i+1:j]
5 A[i]=key
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 在已排序的子陣列中使用二分搜尋尋找插入位置。
- 穩定性(stable):相同鍵值的新元素必須插在原有相同元素的後方。
- 二分搜尋的時間複雜度為 。
- 陣列索引從 開始。
對於已排序的 ,插入 key 時,應尋找第一個滿足
的位置。若所有元素都小於或等於 key,則插入位置為 。
不能尋找第一個 的位置,因為那會將新元素插在相同元素之前,破壞穩定性。
解題方法
使用「找第一個大於 key 的位置」的二分搜尋,即 upper_bound。
設定:
left = pright = q+1
其中 q+1 是可能的插入位置,不必真的存取 。
每次取中間位置:
- 若 ,表示
mid的元素可以放在key前面,因此插入位置應在右側,令left = mid+1。 - 若 ,表示
mid可能是插入位置,令right = mid。
當 left == right 時,即找到第一個大於 key 的位置。
二分搜尋虛擬碼
Binary-search(A, p, q, key)
left = p
right = q + 1
while left < right
mid = floor((left + right) / 2)
if A[mid] <= key
left = mid + 1
else
right = mid
return left
回傳值 left 即為插入位置 i。
配合題目中的 Insertion-sort2:
第 23 題10 分
Given the following pseudo code of Dijkstra algorithm, please point out the errors of the pseudo code. (10 points)
1 procedure Dijkstra(Graph, source):
2 create vertex set Q
3 for each vertex v in Graph:
4 distance[v] ← INFINITY
5 previous[v] ← UNDEFINED
6 if source!=v:
7 add v to Q
8 distance[source] ← 0
9 while Q is not empty:
10 u ← vertex in Q with max_distance[u]
11 remove u from Q
12 for each neighbor v of u:
13 alternative ← distance[u] - length(u, v)
14 if alternative < distance[v]:
15 distance[v] ← alternative
16 u ← previous[v]
17 return distance[], previous[]
登入後即可作答並保存紀錄。
核心觀念
本題考查 Dijkstra 單源最短路徑演算法的正確流程。其核心定義如下:
distance[v]:目前已知的 source 到頂點 的最短距離估計值。previous[v]:最短路徑上,頂點 的前一個頂點。- :尚未確定最短距離的頂點集合。
- 每次從 中取出目前
distance最小的頂點 ,將其視為已確定。 - 對 的每個鄰居 進行鬆弛(relaxation):
若
則更新:
並令
Dijkstra 演算法要求圖上的邊權重皆為非負數,即:
錯誤一:第 10 行應選擇最小距離,而非最大距離
原始程式:
u ← vertex in Q with max_distance[u]
錯誤原因:Dijkstra 的貪婪策略是每次選擇目前距離估計值最小的未處理頂點。因此應改為:
u ← vertex in Q with min_distance[u]
也就是選擇滿足下式的頂點:
若選擇最大距離頂點,無法保證先確定的頂點已經是最短距離,演算法的正確性會失效。
錯誤二:第 13 行應使用加法,而非減法
原始程式:
alternative ← distance[u] - length(u, v)
錯誤原因:從 source 經由 到達 的路徑長度,應為目前到 的距離加上邊 的長度:
因此正確程式為:
alternative ← distance[u] + length(u, v)
使用減法會使邊長越大,計算出的路徑距離反而越小,與最短路徑的定義矛盾。
錯誤三:第 16 行的指定方向相反
原始程式:
u ← previous[v]
錯誤原因:當經由 到達 的路徑較短時,應記錄「 的前驅是 」,而不是修改目前處理的頂點 。
正確程式為:
previous[v] ← u
其意義為:
如此才能在演算法結束後,從目標頂點沿著 previous 陣列反向回溯出完整最短路徑。
其他程式行的判斷
第 6~7 行
if source!=v:
add v to Q
此段邏輯正確,因為 source 的最短距離已知為 ,不需要先放入未處理集合 。其效果等同於:
Q ← all vertices in Graph except source
第 4~5 行
distance[v] ← INFINITY
previous[v] ← UNDEFINED
第 24 題10 分
Please construct the minimum spanning tree (MST) for the given graph using Kruskal's Algorithm. (6 points) What is the weight of the MST? (4 points)
🖼️【此處有附圖,請對照原卷】
登入後即可作答並保存紀錄。
本題要求使用 Kruskal 演算法構建最小生成樹 (MST),並計算其權重。
給定的圖如下:
頂點: {a, b, c, d, f, g} (共 6 個頂點)
邊及其權重:
- (a, f): 7
- (a, b): 23
- (b, d): 20
- (b, c): 19
- (d, f): 11
- (d, c): 15
- (f, g): 13
- (c, g): 9
Kruskal 演算法的步驟:
- 將圖中所有的邊按權重從小到大排序。
- 初始化一個空的 MST 集合,其中包含所有頂點但沒有邊。
- 依序考慮排序後的邊:如果加入一條邊不會在 MST 中形成環,則將該邊加入 MST。
- 重複步驟 3,直到 MST 包含 V-1 條邊(其中 V 是頂點數量)。
步驟 1: 邊按權重排序
- (a, f): 7
- (c, g): 9
- (d, f): 11
- (f, g): 13
- (d, c): 15
- (b, c): 19
- (b, d): 20
- (a, b): 23
步驟 2: 初始化 MST
- 頂點集合 V = {a, b, c, d, f, g}
- MST 邊集合 E' = {}
- 當前權重 W = 0
- 使用 Disjoint Set Union (DSU) 結構來檢查環。初始時,每個頂點都在自己的集合中。
步驟 3: 依序加入邊
-
考慮邊 (a, f) 權重 7:
- 頂點 a 和 f 不在同一個集合。
- 加入邊 (a, f) 到 E'。
- 合併 a 和 f 的集合。
- E' = {(a, f)}, W = 7
- 集合: {a, f}, {b}, {c}, {d}, {g}
-
考慮邊 (c, g) 權重 9:
- 頂點 c 和 g 不在同一個集合。
- 加入邊 (c, g) 到 E'。
- 合併 c 和 g 的集合。
- E' = {(a, f), (c, g)}, W = 7 + 9 = 16
- 集合: {a, f}, {b}, {c, g}, {d}
-
考慮邊 (d, f) 權重 11:
- 頂點 d 和 f 不在同一個集合(d 在 {d},f 在 {a, f})。