113 年 國立中正大學資訊管理學系碩士班乙組《資料結構》
第 1 題6 分
If n is 8, then what the variable space requirement of this program is?
float sum(float list[], int n)
{
float tempsum = 0;
for (int i = 0; i<n; i++)
tempsum += list[i];
return tempsum;
}
登入後即可作答並保存紀錄。
核心觀念
空間需求可分為:
其中:
- :固定空間,與輸入規模無關。
- :變動空間,會隨輸入規模增加而增加。
本題採用資料結構教材對「變動空間」的定義。float list[] 在 C 的函式參數中會被視為指標,函式只接收陣列首位址,不會複製整個陣列;經典教材對此迭代版本的 sum 也定義其變動空間為 。教材範例
解題方法
逐一判斷程式中的變數是否會隨 增加而配置更多空間:
list[]:實際上是指標,只儲存陣列首位址,不會在函式內建立 個float。n:一個整數,固定大小。tempsum:一個float,固定大小。i:一個整數,迴圈中反覆使用同一個變數,不會每次迭代新增空間。
第 2 題6 分
Calculate the total steps of the following function.
float rsum(float list[ ], int n)
{
if (n)
return rsum(list, n-1) + list[n-1];
return list[0];
}
登入後即可作答並保存紀錄。
核心觀念
本題考查遞迴函式的執行步驟與遞迴關係式。n 每次遞減 ,直到 ,因此所有遞迴呼叫形成一條長度為 的鏈。
題目未明定「一步」的細部分解方式;以下採用資料結構教材常見的計數口徑:
- 基底情況
return list[0]計 步。 - 每個非基底呼叫除遞迴子呼叫外,還需執行一次陣列取值與一次加法,共 步。
- 子呼叫的成本納入下一層遞迴,不重複計算。
關鍵程式碼為:
if (n)
return rsum(list, n - 1) + list[n - 1];
return list[0];
解題方法
設 為執行 rsum(list, n) 所需的總步驟數。
當 時,不再遞迴,直接執行:
return list[0];
所以:
當 時,函式先執行一次 rsum(list, n-1),其成本為 ;遞迴返回後,再取出 list[n-1] 並進行加法,共增加 步。因此:
展開遞迴關係式:
第 3 題12 分
Please transform the expressions from prefix to postfix.
(A) -+-/abc*de*ac
(B) -/*a+bcdg
登入後即可作答並保存紀錄。
解題要點
- 由右至左掃描前綴式。
- 碰到運算元(變數)直接壓入堆疊。
- 碰到二元運算子時,彈出兩個堆疊頂端項op1、op2,形成新的後綴子式
op1 op2 operator,再壓回堆疊。 - 最後堆疊唯一項即為完整的後綴式。
(A) -+-/abc*de*ac
| 逆序掃描 | 堆疊變化 |
|---|---|
| c | c |
| a | c , a |
| * | ac* |
| e | ac* , e |
| d | ac* , e , d |
| * | ac* , de* |
| c | ac* , de* , c |
| b | ac* , de* , c , b |
| a | ac* , de* , c , b , a |
| / | ac* , de* , c , ab/ |
第 4 題24 分
Which(s) is/are true in the following descriptions?
(A) &a->val means (&a)->val
(B) The worst-case complexity of the maze is O(mp), where m and p are the number of rows and columns of the maze respectively.
(C) a%bc=3 means (a%(bc))==3
(D) a=3 || b==4 && c==5 means ((a==3) || (b==4)) && (c==5)
(E) The time complexity of O(2^n) is higher than O(n!).
(F) Prefix notation requires the use of parentheses to indicate the precedence of operands.
登入後即可作答並保存紀錄。
(A) &a->val 依照 C 語言的結合性,-> 的優先度高於 &,因此被解析為 &(a->val),而非 (&a)->val,故 錯誤。
(B) 迷宮的每格只會被訪問一次,最壞情況需遍歷全部 個格子,時間複雜度為 ,正確。
(C) % 與 * 同階且自左至右結合,a%b*c 等價於 ,不是 ,故 錯誤。
第 5 題12 分
The following is a circular queue. Please find and correct the errors.
element deleteq()
{
element item; /* hint: MAX_QUEUE_SIZE */
front = front+1;
if (front = rear)
return queueEmpty();
return queue[front];
}
登入後即可作答並保存紀錄。
核心觀念
本題考查兩個重點:
- 循環佇列的索引循環
- 佇列刪除操作與空佇列判斷
採用常見的循環佇列表示法:
front指向「目前佇列第一個元素之前的位置」。rear指向目前佇列最後一個元素的位置。- 空佇列條件:
front往前移動一格時,必須使用取餘數,使索引超過陣列尾端後回到陣列開頭:
此表示法會保留一個空格,因此實際可存放的元素數量最多為 。
解題方法
刪除循環佇列的第一個元素時,正確順序如下:
- 先判斷佇列是否為空。
- 將
front往前移動一格,並處理循環。 - 取出新的
front位置上的元素。 - 回傳該元素。
若先執行 front = front + 1,當佇列原本為空時,front 與 rear 會被錯誤地分開,導致空佇列判斷失效。因此,空佇列必須在移動索引前判斷。
原程式的錯誤
1. front = front+1 未處理循環
原程式:
front = front+1;
當 front 已經位於陣列最後一格時,再加一會變成 MAX_QUEUE_SIZE,超出合法索引範圍 至 。
正確寫法:
front = (front + 1) % MAX_QUEUE_SIZE;
2. if (front = rear) 使用指定運算子
原程式:
if (front = rear)
= 是指定運算子,會把 rear 的值指定給 front,而不是比較兩者是否相等。指定後,條件式的結果還會依 rear 的值判斷,造成程式邏輯錯誤。
比較相等必須使用 ==:
if (front == rear)
3. 空佇列判斷位置錯誤
原程式先移動 front,再判斷 front == rear:
front = front+1;
if (front == rear)
第 6 題20 分
Please complete the code of function invert to perform the action for "Invert single linked list".
typedef struct list_node *list_pointer;
typedef struct list_node {
char data;
list_pointer link;
};
list_pointer invert(list_pointer lead)
{
list_pointer middle, trail;
middle = NULL;
while (.......) {
}
return middle;
}
登入後即可作答並保存紀錄。
核心觀念
本題考查單向鏈結串列的「就地反轉」。每個節點只有一個 link 指標,原本方向為:
反轉後必須變成:
不建立新節點,只重新設定各節點的 link。
三個指標的角色如下:
lead:目前尚未處理的節點。middle:已經完成反轉的部分串列首節點。trail:暫存lead原本的下一個節點。
解題方法
每次處理 lead 時,必須依照下列順序操作:
-
先保存下一個節點:
trail = lead->link; -
將目前節點指向已反轉的部分:
lead->link = middle; -
將目前節點設為反轉串列的新首節點:
middle = lead; -
移至尚未處理的部分:
lead = trail;
因此迴圈條件必須是 lead != NULL。當 lead 變成 NULL 時,代表所有節點都已處理完畢,middle 即為反轉後的首節點。
完整程式碼
list_pointer invert(list_pointer lead)
{
list_pointer middle, trail;
middle = NULL;
while (lead != NULL) {
trail = lead->link;
lead->link = middle;
middle = lead;
lead = trail;
}
return middle;
}
指標變化示例
假設原串列為:
A -> B -> C -> NULL
初始狀態:
middle = NULL
lead = A
第一次迴圈:
第 7 題20 分
If the order of moving is as follows (left graph), please draw the maze path in the right graph (where 1 is blocked path and 0 is through path).
🖼️【此處有附圖,請對照原卷】
登入後即可作答並保存紀錄。
核心觀念
本題考查迷宮的深度優先搜尋與回溯。由目前位置依指定方向順序逐一嘗試;遇到牆壁、邊界或已走過的格子就略過,走進無路可走的位置時便回溯,改試下一個方向。
解題方法
左圖的移動順序為: 向東、 東北、 北、 西北、 西、 西南、 南、 東南。右圖是 迷宮,入口接在第 列第 欄,出口接在第 列第 欄;以 表示格子座標。
從 沿東方前進至 、。頂列右側的通路會走到死路,因此搜尋回溯至 ,再走西南方向進入 。
在 ,東、東北、北、西北方向分別遇到牆或已走過的格子;依順序接著檢查西方,發現 是尚未走過的通路,因此先走到 ,再向南到 。從此沿第 列向東走至 ,再向南到 。在 ,西南方向的 可通行,接著向東到 ,抵達出口。
路徑格以 P 標示;0 是未列入最終路徑的通路,1 是阻塞格: