114 公務人員升官等薦任 資訊處理 資料結構 考古題詳解
第 一 題22 分
費伯納西數列(Fibonacci Sequence)定義如下:
,,
請完成下列各題:
(一) 使用遞迴方法(Recursion)撰寫虛擬碼,計算第 項的費伯納西數。(8 分)
(二) 使用動態規劃方法(Dynamic Programming)撰寫虛擬碼,透過自底向上(Bottom-up)的方式計算第 項的費伯納西數。(8 分)
(三) 比較兩個方法的時間複雜度(Time Complexity)。(6 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查費伯納西數列的遞迴定義,以及遞迴與動態規劃的實作方式和時間複雜度。
數列定義為:
直接遞迴會重複計算許多相同的子問題;自底向上的動態規劃則依序計算並保存已求出的數值,避免重複計算。
(一)遞迴方法
遇到 或 時,直接回傳定義的基底值;其他情況依定義將前兩項相加。
FibonacciRecursive(n)
if n = 0
return 0
if n = 1
return 1
return FibonacciRecursive(n - 1)
+ FibonacciRecursive(n - 2)
以 為例:
此方法直接呈現數列的數學定義,但會在遞迴展開時重複計算,例如 在計算 時會被求出不只一次。
(二)自底向上的動態規劃
從已知的基底值 、 開始,依序計算 至 ,並將每一項保存下來。
FibonacciBottomUp(n)
if n = 0
return 0
建立陣列 F[0..n]
F[0] ← 0
F[1] ← 1
for i ← 2 to n
F[i] ← F[i - 1] + F[i - 2]
return F[n]
例如計算 :
第 二 題22 分
已知 B+-tree 的階數(Order)為 。葉節點至多可存放 2 個鍵值,至少須存放 1 個鍵值;內部節點至多可有 3 個子節點,至少須有 2 個子節點。
當節點因插入而溢位時,規定葉節點分裂時將右子節點之第一個鍵值提升至父節點,內部節點分裂時則將中間鍵值提升至父節點。請完成下列各題:
(一) 依序插入 17、5、12、23、7、19、3、30 等 8 個鍵值以建構 B+-tree。
請逐步說明並繪製每次插入後之樹形結構。(12 分)
(二) 承接(一)之結果,依序刪除 7、23 與 5 等三個鍵值。刪除過程中若需借值時,一律自右兄弟節點借取;若無法借值,則與左兄弟節點合併。
請逐步說明並繪製每次刪除鍵值後之樹形結構。(6 分)
(三) 承接(一)之結果,說明在該 B+-tree 中搜尋鍵值 19 之完整過程,並列出查找時經過之節點及比較順序。(4 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查 B+-tree 的插入、溢位分裂、刪除後的再平衡,以及依分隔鍵逐層搜尋。
- 葉節點最多存放 個鍵值,至少存放 個鍵值。葉節點溢位時,將鍵值由小到大分成左右兩個葉節點,並把右葉節點的第一個鍵值複製到父節點作為分隔鍵;該鍵值仍保留在葉節點。
- 內部節點最多有 個子節點、至少有 個子節點。內部節點溢位時,將中間鍵值提升至父節點;左右兩側的鍵值與子節點分別留在分裂後的左右節點。
- B+-tree 的資料鍵值都存放於葉節點;內部節點的鍵值用來指引搜尋。
- 刪除後,若節點低於最低容量,先依題目規定自右兄弟借值;右兄弟不能提供時,與左兄弟合併,並同步更新父節點分隔鍵。
以下以方括號表示葉節點,以圓括號表示內部節點;例如 是葉節點, 是含有分隔鍵 的內部節點。
(一)依序插入 8 個鍵值
插入 17
根節點同時也是葉節點:
[17]
插入 5
[5,17]
插入 12
排序後成為 ,超過葉節點容量 。分成 與 ,將右葉節點第一個鍵值 複製到父節點,形成新根:
(12)
/ \
[5] [12,17]
插入 23
,進入右葉節點,該葉節點成為 ,再分成 與 ;將 複製至父節點:
(12,17)
/ | \
[5] [12] [17,23]
插入 7
,插入最左葉節點:
(12,17)
/ | \
[5,7] [12] [17,23]
插入 19
,插入最右葉節點。該葉節點成為 ,分裂為 與 ,將 複製到父節點。父節點原有兩個鍵值,加入後成為 ,有四個子節點,超過內部節點最多 個子節點的限制。
內部節點分裂時提升中間鍵值 ,左右兩側分別保留分隔鍵 與 :
(17)
/ \
(12) (19)
/ \ / \
[5,7] [12] [17] [19,23]
插入 3
,再依左側內部節點的分隔鍵 導向 。插入後成為 ,分裂為 與 ,將右葉節點第一個鍵值 複製至父節點:
(17)
/ \
(5,12) (19)
/ | \ / \
[3] [5,7] [12] [17] [19,23]
插入 30
,導向右側內部節點 ,再進入右葉節點 。插入後成為 ,分裂為 與 ,將 複製至父節點:
(17)
/ \
(5,12) (19,23)
/ | \ / | \
[3] [5,7] [12][17] [19] [23,30]
這是第(一)小題完成後的 B+-tree。
第 三 題24 分
已知待排序數列如下:
其中兩個 36 的數值相同,但以底線標示其中一個 36,以便在排序過程中追蹤其相對次序。
請完成下列各題:
(一) 說明何謂穩定排序(Stable Sort),並解釋若演算法不屬於穩定排序,在處理相同鍵值時會造成什麼影響。(6 分)
(二) 使用選擇排序(Selection Sort)對上述數列進行排序,並逐步描述每次選擇與交換的過程,最後給出排序後的結果。(6 分)
(三) 使用合併排序(Merge Sort)對上述數列進行排序,並描述拆分與合併的過程,最後給出排序後的結果。(6 分)
(四) 使用基數排序(Radix Sort)對上述數列進行排序,並描述逐位(個位數、十位數)的桶排序(Bucket Sort)過程,最後給出排序後的結果。(6 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查穩定排序的定義,以及選擇排序、合併排序、基數排序的操作方式。排序鍵值相同時,以底線標示的 記為 ,未標示者記為 ,藉此追蹤兩者的相對次序。
穩定排序(Stable Sort):若兩筆資料的鍵值相同,排序後仍保留它們在原始數列中的先後次序。本題原始次序是 在 之前;穩定排序後也必須維持此順序。若排序演算法不穩定,相同鍵值的資料可能交換相對位置;當資料還帶有其他欄位時,即使主鍵相同,這些欄位的先後關係也可能改變。
解題方法
(一)穩定性說明(6 分)
穩定性只比較鍵值相同的資料:若排序前 在 之前,且兩者鍵值相同,排序後仍讓 在 之前,則此排序為穩定排序。
本題可用兩個 驗證:穩定排序須保留 的次序;若排序後變成 ,即表示相對次序改變,該次排序不穩定。
(二)選擇排序(6 分)
每一趟從尚未排序的部分找出最小值,與該部分的第一個元素交換。以下採用標準的「交換式選擇排序」。
初始數列:
| 趟數 | 未排序部分的最小值 | 交換後數列 |
|---|---|---|
| 第 1 趟 | ||
| 第 2 趟 | ||
| 第 3 趟 | ||
| 第 4 趟 | ||
| 第 5 趟 | ||
| 第 6 趟 | ||
| 第 7 趟 |
第 2 趟把位置 2 的 與位置 8 的 交換,原本位於 後方的 因此移到未標示的 前面。這說明標準選擇排序不具穩定性。
(三)合併排序(6 分)
合併排序先遞迴拆分,再將已排序的小數列合併。合併時遇到相同鍵值,若優先取左半部的元素,便能保留原始相同鍵值元素的先後次序。
拆分:
第 四 題16 分
19 世紀電報傳輸以訊號數計費。為了降低成本,電報公司決定採用霍夫曼編碼(Huffman Coding)壓縮電文。
假設要傳輸字母 TURING,其出現次數如下:
(15 次)、(7 次)、(6 次)、(6 次)、(5 次)、(5 次)。
在建構過程中,每次取出權重最小的兩個節點合併;若兩者權重相同,則依字母順序決定先後。請完成下列各題:
(一) 依步驟建構霍夫曼樹,並寫出各字母的編碼。(10 分)
(二) 比較固定長度編碼(假設每個字母以 3 位元表示)與霍夫曼編碼,並計算壓縮率(需列計算過程)。(6 分)
登入後即可作答並保存紀錄。
核心觀念
霍夫曼編碼(Huffman Coding)是依符號出現頻率建立最佳前綴碼的方法。建樹時反覆取出權重最小的兩個節點合併,新節點的權重為兩者相加,直到只剩一個根節點。將每個節點的左分支標為 、右分支標為 ,從根走到葉節點的位元序列就是該字母的編碼。
本題指定權重相同時依字母順序決定先後,因此也需為合併後的內部節點指定排序標籤:以該子樹所含字母中排序最前者作為標籤。
解題方法
先將字母按權重由小到大排列:
依規則每次合併最小的兩個節點:
| 步驟 | 取出的節點 | 合併結果 |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 | ||
| 5 | 根節點 |
第 1 步的 、 權重相同,按字母順序先取 ;第 2 步的 、 同理先取 。之後每一步都是取當下權重最小的兩個節點。
依合併順序建立樹,左右分支由左至右分別標記 、:
(44)
/ \
(17) (27)
/ \ / \
U(7) (10) (12) T(15)
/ \ / \
G(5) N(5) I(6) R(6)
由根節點往下讀取分支標記,可得:
| 字母 | 霍夫曼編碼 | 碼長 |
|---|---|---|
| 2 | ||
| 2 | ||
| 3 | ||
| 3 | ||
| 3 | ||
| 3 |
第 五 題16 分
下圖為一有向圖(Directed Graph)。請完成下列各題:
(一) 畫出圖 的相鄰串列(Adjacency List)。(4 分)
(二) 畫出圖 的相鄰矩陣(Adjacency Matrix)。(4 分)
(三) 從節點 開始,寫出廣度優先搜尋(Breadth-First Search, BFS)的節點拜訪順序。(4 分)
(四) 從節點 開始,寫出深度優先搜尋(Depth-First Search, DFS)的節點拜訪順序。(4 分)
登入後即可作答並保存紀錄。
核心觀念
有向圖的相鄰串列記錄每個頂點沿箭頭方向可到達的頂點;相鄰矩陣以列表示起點、欄表示終點,若有邊則記為 ,沒有則記為 。
BFS 使用佇列,依層次拜訪;DFS 沿著尚未拜訪的鄰點繼續深入,再回溯。題目沒有指定同一頂點的鄰點處理順序,因此以下採頂點字母順序處理,亦即 。
解題方法
依圖中箭頭可整理出邊:
(一)相鄰串列
按字母順序列出各頂點的出邊:
(二)相鄰矩陣
列為起點、欄為終點,頂點順序皆為 :