113 年 國立中正大學資訊管理學系碩士班乙組《資料結構》

📄 試題原卷 免費註冊後即可對照原始考卷 PDF免費註冊

第 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;
}

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

空間需求可分為:

S(P)=C+SP(I)S(P)=C+S_P(I)

其中:

  • CC:固定空間,與輸入規模無關。
  • SP(I)S_P(I):變動空間,會隨輸入規模增加而增加。

本題採用資料結構教材對「變動空間」的定義。float list[] 在 C 的函式參數中會被視為指標,函式只接收陣列首位址,不會複製整個陣列;經典教材對此迭代版本的 sum 也定義其變動空間為 00。教材範例

解題方法

逐一判斷程式中的變數是否會隨 nn 增加而配置更多空間:

  • list[]:實際上是指標,只儲存陣列首位址,不會在函式內建立 nn 個 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 每次遞減 11,直到 n=0n=0,因此所有遞迴呼叫形成一條長度為 n+1n+1 的鏈。

題目未明定「一步」的細部分解方式;以下採用資料結構教材常見的計數口徑:

  • 基底情況 return list[0] 計 11 步。
  • 每個非基底呼叫除遞迴子呼叫外,還需執行一次陣列取值與一次加法,共 22 步。
  • 子呼叫的成本納入下一層遞迴,不重複計算。

關鍵程式碼為:

if (n)
    return rsum(list, n - 1) + list[n - 1];

return list[0];

解題方法

設 T(n)T(n) 為執行 rsum(list, n) 所需的總步驟數。

當 n=0n=0 時,不再遞迴,直接執行:

return list[0];

所以:

T(0)=1T(0)=1

當 n≥1n\ge 1 時,函式先執行一次 rsum(list, n-1),其成本為 T(n−1)T(n-1);遞迴返回後,再取出 list[n-1] 並進行加法,共增加 22 步。因此:

T(n)=T(n−1)+2T(n)=T(n-1)+2

展開遞迴關係式:

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

第 3 題12 分

Please transform the expressions from prefix to postfix.
(A) -+-/abc*de*ac
(B) -/*a+bcdg

登入後即可作答並保存紀錄。

這一題的完整詳解

解題要點

  1. 由右至左掃描前綴式。
  2. 碰到運算元(變數)直接壓入堆疊。
  3. 碰到二元運算子時,彈出兩個堆疊頂端項op1、op2,形成新的後綴子式 op1 op2 operator,再壓回堆疊。
  4. 最後堆疊唯一項即為完整的後綴式。

(A) -+-/abc*de*ac

逆序掃描堆疊變化
cc
ac , a
*ac*
eac* , e
dac* , e , d
*ac* , de*
cac* , de* , c
bac* , de* , c , b
aac* , 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) 迷宮的每格只會被訪問一次,最壞情況需遍歷全部 m×pm \times p 個格子,時間複雜度為 O(mp)O(mp),正確。

(C) % 與 * 同階且自左至右結合,a%b*c 等價於 (a%b)×c(a\%b)\times c,不是 a%(b×c)a\% (b\times 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];
}

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查兩個重點:

  1. 循環佇列的索引循環
  2. 佇列刪除操作與空佇列判斷

採用常見的循環佇列表示法:

  • front 指向「目前佇列第一個元素之前的位置」。
  • rear 指向目前佇列最後一個元素的位置。
  • 空佇列條件:
front=rearfront = rear
  • front 往前移動一格時,必須使用取餘數,使索引超過陣列尾端後回到陣列開頭:
front←(front+1) mod MAX_QUEUE_SIZEfront \leftarrow (front+1)\bmod MAX\_QUEUE\_SIZE

此表示法會保留一個空格,因此實際可存放的元素數量最多為 MAX_QUEUE_SIZE−1MAX\_QUEUE\_SIZE-1。

解題方法

刪除循環佇列的第一個元素時,正確順序如下:

  1. 先判斷佇列是否為空。
  2. 將 front 往前移動一格,並處理循環。
  3. 取出新的 front 位置上的元素。
  4. 回傳該元素。

若先執行 front = front + 1,當佇列原本為空時,front 與 rear 會被錯誤地分開,導致空佇列判斷失效。因此,空佇列必須在移動索引前判斷。

原程式的錯誤

1. front = front+1 未處理循環

原程式:

front = front+1;

當 front 已經位於陣列最後一格時,再加一會變成 MAX_QUEUE_SIZE,超出合法索引範圍 00 至 MAX_QUEUE_SIZE−1MAX\_QUEUE\_SIZE-1。

正確寫法:

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 指標,原本方向為:

A→B→C→NULLA \rightarrow B \rightarrow C \rightarrow NULL

反轉後必須變成:

C→B→A→NULLC \rightarrow B \rightarrow A \rightarrow NULL

不建立新節點,只重新設定各節點的 link。

三個指標的角色如下:

  • lead:目前尚未處理的節點。
  • middle:已經完成反轉的部分串列首節點。
  • trail:暫存 lead 原本的下一個節點。

解題方法

每次處理 lead 時,必須依照下列順序操作:

  1. 先保存下一個節點:

    trail = lead->link;
    
  2. 將目前節點指向已反轉的部分:

    lead->link = middle;
    
  3. 將目前節點設為反轉串列的新首節點:

    middle = lead;
    
  4. 移至尚未處理的部分:

    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).
🖼️【此處有附圖,請對照原卷】

🖼️ 本題含圖表,以下為原卷對應頁面:
原卷第 3 頁

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查迷宮的深度優先搜尋與回溯。由目前位置依指定方向順序逐一嘗試;遇到牆壁、邊界或已走過的格子就略過,走進無路可走的位置時便回溯,改試下一個方向。

解題方法

左圖的移動順序為:00 向東、11 東北、22 北、33 西北、44 西、55 西南、66 南、77 東南。右圖是 5×55\times5 迷宮,入口接在第 11 列第 11 欄,出口接在第 55 列第 55 欄;以 (列,欄)(列,欄) 表示格子座標。

從 (1,1)(1,1) 沿東方前進至 (1,2)(1,2)、(1,3)(1,3)。頂列右側的通路會走到死路,因此搜尋回溯至 (1,3)(1,3),再走西南方向進入 (2,2)(2,2)。

在 (2,2)(2,2),東、東北、北、西北方向分別遇到牆或已走過的格子;依順序接著檢查西方,發現 (2,1)(2,1) 是尚未走過的通路,因此先走到 (2,1)(2,1),再向南到 (3,1)(3,1)。從此沿第 33 列向東走至 (3,5)(3,5),再向南到 (4,5)(4,5)。在 (4,5)(4,5),西南方向的 (5,4)(5,4) 可通行,接著向東到 (5,5)(5,5),抵達出口。

路徑格以 P 標示;0 是未列入最終路徑的通路,1 是阻塞格:

🔒

後續完整解題步驟與【答案】

免費註冊,享三天全站完整詳解閱覽。

免費註冊

其他考古題