108 關務特考三等 資訊處理 資料結構 考古題詳解
第 一 題20 分
下列程式函式 以 C 語言語法呈現,用以對雙向鏈結串列(doubly linked list)進行處理。請依據該函式回答問題。
void doit(struct node **head){ struct node *temp = NULL; struct node *current = *head;
while(current != NULL){
temp = current->prev;
current->prev = current->next;
current->next = temp;
current = current->prev;
}
if(temp != NULL)
*head = temp->prev;
}
(一)若 指向一個雙向鏈結串列如下,其中 指向 NULL, 指向資料為 21 的節點。請顯示並說明 執行過後該串列變化結果。(10 分)
鏈結串列: NULL 17 21 35 74 95 NULL
指向資料為 17 的節點。
🖼️【此處有附圖,請對照原卷】
(二)若 指向一個雙向鏈結串列如下,其中 指向資料為 17 的節點, 指向資料為 35 的節點。請顯示並說明 執行過後該串列的變化結果。(5 分)
鏈結串列: NULL 17 21 35 74 95 NULL
指向資料為 21 的節點。
🖼️【此處有附圖,請對照原卷】
(三)若 指向一個環狀雙向鏈結串列(circular doubly linked list),請說明 是否仍能順利執行。(5 分)
登入後即可作答並保存紀錄。
核心觀念
此題考雙向鏈結串列的指標更新。對每個走訪到的節點,程式先保存原本的 prev,再交換該節點的 prev 與 next。交換後,current->prev 指向的是該節點原本的 next,因此程式會沿原本的 next 方向前進。
temp 每次保存目前節點原本的 prev。迴圈結束後,若 temp 不為 NULL,程式將 *head 設為 temp->prev。
解題方法
依序追蹤每個被走訪節點的 prev、next,並留意走訪起點是否為串列的第一個節點。若從第一個節點開始,所有節點都會交換;若從中間節點開始,其前方節點不會被處理。
(一)從資料為 17 的節點開始
走訪順序為 ,五個節點的 prev、next 都交換。最後,temp 指向 74;此時 temp->prev 指向 95,因此 X 改指向 95。
執行後的串列為:
也就是原串列順序反轉,X 指向資料為 95 的節點。
(二)從資料為 21 的節點開始
走訪順序為 ,資料為 17 的節點沒有被走訪,因此其指標維持原狀。
第 二 題25 分
給定 為一個以陣列表現的二元搜尋樹(binary search tree)。
(一)若有一些介於 1 及 1,000 的正整數被儲存於 ,且要搜尋數字 364,請說明搜尋過程是否有可能為:3、400、388、220、267、383、382、279、364?(5 分)
(二)若有一些介於 1 及 1,000 的正整數被儲存於 ,且要搜尋數字 364,請說明搜尋過程是否有可能為:926、203、912、241、913、246、364?(5 分)
(三)若對 進行前序遍歷(pre-order traversal)的結果為 30、20、10、15、25、23、39、35、42。請說明以後序遍歷(post-order traversal)結果為何。(5 分)
(四)若對 進行後序遍歷(post-order traversal)的結果為 25、20、34、37、31、49、46、57、60、52、41。請說明若以中序遍歷(in-order traversal),結果為何。(5 分)
(五)請說明可將二元搜尋樹 轉換為最小堆積(min heap)的程序為何?(10 分)
登入後即可作答並保存紀錄。
核心觀念
本題評量二元搜尋樹(Binary Search Tree, BST)與堆積(Heap)的核心理論與實作,包含四大觀念:
- 二元搜尋樹的定義與搜尋特性:
- 對於 BST 中的任一節點 ,其左子樹中所有節點的鍵值皆小於 的鍵值;其右子樹中所有節點的鍵值皆大於 的鍵值(即 )。
- 在搜尋目標鍵值 時,每次與節點 比較:
- 若 ,則搜尋路徑轉向左子樹,同時確立往後所有受檢節點之上界必小於 。
- 若 ,則搜尋路徑轉向右子樹,同時確立往後所有受檢節點之下界必大於 。
- 搜尋過程中的每一步,皆使目標所在的合法數值區間 持續限縮,後續拜訪的節點數值絕不可超出已確立的有效區間。
- 二元搜尋樹的走訪特性:
- 中序遍歷(In-order Traversal)的單調性:對任何合法的二元搜尋樹進行中序走訪(左 根 右),其輸出序列必然為由小到大的嚴格遞增排序序列。
- 樹的重建唯一性:已知前序(Pre-order,根 左 右)或後序(Post-order,左 右 根),搭配 BST 中序必然為遞增排序的性質,即可唯一決定二元樹的結構。
- 最小堆積(Min Heap)的定義與要件:
- 結構性質(Shape Property):必須為完全二元樹(Complete Binary Tree)。若以一維陣列表示,包含 個節點的堆積必須緊湊連續存放於索引 到 。
- 堆積性質(Heap Property):任一非根節點 的值,皆必須大於或等於其父節點的值,即 ,根節點恆為全樹最小值。
解題方法與詳細推導
(一)判斷搜尋 364 之序列是否可能為:3、400、388、220、267、383、382、279、364
- 方法:透過「搜尋區間收縮法」追蹤每一步的合法範圍。初始有效區間為 。
- 逐步推導:
- 拜訪 3:目標 ,向右子樹搜尋。確立下界為 3,後續合法區間為 。
- 拜訪 400:。目標 ,向左子樹搜尋。確立上界為 400,後續合法區間為 。
- 拜訪 388:。目標 ,向左子樹搜尋。確立上界為 388,後續合法區間為 。
- 拜訪 220:。目標 ,向右子樹搜尋。確立下界為 220,後續合法區間為 。
- 拜訪 267:。目標 ,向右子樹搜尋。確立下界為 267,後續合法區間為 。
- 拜訪 383:。目標 ,向左子樹搜尋。確立上界為 383,後續合法區間為 。
- 拜訪 382:。目標 ,向左子樹搜尋。確立上界為 382,後續合法區間為 。
- 拜訪 279:。目標 ,向右子樹搜尋。確立下界為 279,後續合法區間為 。
- 拜訪 364:,成功找到目標節點。
- 結論:序列中每一個受檢節點均嚴格落在當前的有效邊界之內,未違反二元搜尋樹之性質,故此搜尋過程有可能。
(二)判斷搜尋 364 之序列是否可能為:926、203、912、241、913、246、364
- 方法:透過「搜尋區間收縮法」檢驗節點是否落入合法區間。
- 逐步推導:
- 拜訪 926:目標 ,向左子樹搜尋。後續合法區間限縮為 。
- 拜訪 203:。目標 ,向右子樹搜尋。後續合法區間限縮為 。
- 拜訪 912:。目標 ,向左子樹搜尋。後續合法區間限縮為 。
- 拜訪 241:。目標 ,向右子樹搜尋。後續合法區間限縮為 。
- 拜訪 913:檢查其值,。
- 矛盾分析:在第 3 步拜訪 912 時,因目標值 ,搜尋進入 912 的左子樹;依照 BST 定義,912 之左子樹內的所有節點鍵值皆必須小於 912。然而後續出現的節點 913 卻大於 912,直接違反二元搜尋樹的定義。
- 結論:此搜尋過程不可能。
(三)前序遍歷為 30、20、10、15、25、23、39、35、42,求後序遍歷結果
- 方法:
- 藉由 BST 特性,將所有節點鍵值由小到大排序,求得中序遍歷結果:
- 結合前序與中序遍歷遞迴重建二元搜尋樹:
- 前序首個元素為樹根:30。
- 在中序中,30 左側為左子樹 ,30 右側為右子樹 。
- 建構左子樹:
- 前序子序列為 ,故左子樹之根為 20。
- 中序中小於 20 為 (左子樹),大於 20 為 (右子樹)。
- 對 :前序為 ,根為 10,15 為其右小孩。
- 對 :前序為 ,根為 25,23 為其左小孩。
- 建構右子樹:
- 前序子序列為 ,故右子樹之根為 39。
第 三 題30 分
給定以相鄰矩陣(adjacency matrix)表示的圖 ,矩陣中的數字為相鄰兩節點間的距離,若空白則代表兩節點不相鄰。
圖 的相鄰矩陣如下:
(一)請說明若以 Kruskal’s 演算法建立最小生成樹(minimum spanning tree)的過程中,依序被加入生成樹的邊。(5 分)
(二)請說明若以 Prim’s 演算法建立最小生成樹(minimum spanning tree)的過程中,依序被加入生成樹的邊。(5 分)
(三)請說明 Dijkstra’s 演算法的用途,並說明該演算法應用上的限制。(10 分)
(四)請說明將圖 從 節點開始執行 Dijkstra’s 演算法的過程,並顯示節點加入的順序。(10 分)
登入後即可作答並保存紀錄。
核心觀念
本題考三種圖形演算法:
- Kruskal:依邊權重由小至大考慮邊;若加入該邊不會形成環,就納入生成樹。
- Prim:從一個起始節點出發,每次加入連接「已納入節點」與「未納入節點」的最小權重邊。
- Dijkstra:求單一起點到其他節點的最短距離。每次確定目前暫定距離最小的未確定節點,再更新其鄰點距離。
(一)Kruskal 演算法
將圖中邊依權重由小至大排列:
依序選邊,若會形成環則跳過:
- 加入 。
- 加入 。
- 加入 。
- 加入 。
- 加入 。
- 、 都會形成環,跳過。
- 加入 。
- 加入 。
- 加入 ,此時已連通 9 個節點,共有 8 條邊,完成最小生成樹。
依序加入的邊:
總權重為 。
(二)Prim 演算法
題目未指定起始節點,以下以 為起點。每一步從已納入的節點集合,選擇連往集合外且權重最小的邊:
- 從 出發,選 。
- 已納入 ,選 。
- 已納入 ,選 。
- 已納入 ,選 。
- 已納入 ,選 。
- 已納入 ,選 。
- 已納入 ,選 。
- 最後選 ,納入節點 。
從 起始時,依序加入的邊:
(三)Dijkstra 演算法的用途與限制
**用途:**求加權圖中某一起點到其他各節點的最短路徑距離,並可透過前驅節點還原路徑。
第 四 題20 分
請將所給定數字藉由所指定雜湊函數依序置入雜湊表。
雜湊表欄位為 ,索引包含 0、1、2、3、4、⋯;每個桶(bucket)包含槽 1、槽 2。
🖼️【此處有附表,請對照原卷】
(一)若雜湊函數為 ,並以線性探測(linear probing)解決溢位(overflow)問題,請顯示將 15、23、、3、、8、9、11、、、14、10、25、12、0、21 依序置入 11 桶(buckets) 槽(slots)雜湊表的最終結果。(10 分)
(二)若雜湊函數為 ,並以平方探測(quadratic probing)解決溢位(overflow)問題,請顯示將 15、23、、3、、8、9、11、、、14、10、25、12 依序置入 7 桶(buckets) 槽(slots)雜湊表的最終結果。(10 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查雜湊函數、負數取模,以及雜湊碰撞時的探測方法。每個桶有槽 1、槽 2;插入時先檢查指定桶的槽 1,再檢查槽 2。桶已滿時,依題目指定的探測方式尋找下一個可用桶。
負數取模以非負餘數表示,例如 、。
解題方法
(一)線性探測:11 桶 × 2 槽
先計算 。若該桶已滿,就依序檢查下一桶,桶號以 11 為循環。
| 插入數字 | 雜湊桶 | 最後位置 |
|---|---|---|
| 15 | 4 | 4 槽 1 |
| 23 | 1 | 1 槽 1 |
| 10 | 10 槽 1 | |
| 3 | 3 | 3 槽 1 |
| 3 | 3 槽 2 | |
| 8 | 8 | 8 槽 1 |
| 9 | 9 | 9 槽 1 |
| 11 | 0 | 0 槽 1 |
| 8 | 8 槽 2 | |
| 6 | 6 槽 1 | |
| 14 | 3 | 4 槽 2(桶 3 已滿) |
| 10 | 10 | 10 槽 2 |
| 25 | 3 | 5 槽 1(桶 3、4 已滿) |
| 12 | 1 | 1 槽 2 |
| 0 | 0 | 0 槽 2 |
| 21 | 10 | 2 槽 1(桶 10、0、1 已滿) |
最終雜湊表如下:
| 桶 | 槽 1 | 槽 2 |
|---|---|---|
| 0 | 11 | 0 |
| 1 | 23 | 12 |
| 2 | 21 | 空 |
| 3 | 3 | |
| 4 | 15 | 14 |
| 5 | 25 | 空 |
| 6 | 空 | |
| 7 | 空 | 空 |
| 8 | 8 | |
| 9 | 9 | 空 |
| 10 | 10 |
(二)平方探測:7 桶 × 2 槽
以 依序探測桶號:
每次探測到一個桶時,先檢查槽 1,再檢查槽 2。平方探測的桶號偏移依序為 。