114 年 國立中山大學電機工程學系碩士班丙組《資料結構》

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

第 1 題30 分

【此題30分;每小題15分】
①下圖為一個AVL tree,每個node 裡頭的數字代表一筆資料的key值;root的key值為49。
畫出「刪除 key 值為49 的資料」之後的AVL tree。
②承上題,在「刪除key值為49的資料」之後,接著畫出「插入key 值為35的資料」之後
所產生的AVL tree。
49
31
74
19
38
66
79
24
57
69
83
72

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

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

這一題的完整詳解

核心觀念

AVL 樹是二元搜尋樹,且每個節點的左右子樹高度差最多為 11。平衡因子定義為:

BF(v)=h(左子樹)−h(右子樹)\text{BF}(v)=h(\text{左子樹})-h(\text{右子樹})

刪除節點或插入節點後,若有節點的平衡因子超出 −1-1 到 11,就須以旋轉恢復平衡。

題目未指定刪除有兩個子節點的節點時,要採用中序前驅或中序後繼。以下採常用的中序後繼規則:以右子樹中最小的鍵值取代被刪除的鍵值。

解題方法

① 刪除根節點 4949:

4949 有兩個子節點,其中序後繼是右子樹中最小的鍵值 5757。以 5757 取代 4949,再從原位置刪除 5757。此時節點 6666 的左子樹為空,右子樹為 6969(其右子節點為 7272),所以:

BF(66)=0−2=−2\text{BF}(66)=0-2=-2

這是右右型失衡,在 6666 處做一次左旋,得到以 6969 為根、左右子節點分別為 6666 與 7272 的子樹。旋轉後,節點 7474 與根節點 5757 都符合 AVL 平衡條件。

刪除後的 AVL 樹:

🔒

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

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

免費註冊

第 2 題15 分

【此題15分】給定一個陣列A,裡頭包含n個互不相同的整數元素,分別儲存在A[0]至
A[n-1]。寫一個遞迴函式(recursive function),函式名稱為find_max,能在O(n)的時間
內找出陣列A裡頭的最大元素。若你所寫的find_max 函式不為遞迴函式,此題將不給分。

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

這一題的完整詳解

核心觀念

本題考查「遞迴」與「線性搜尋」:

  • 陣列最大值的定義:
    max⁡(A[0],A[1],…,A[n−1])\max(A[0],A[1],\ldots,A[n-1])
  • 將問題縮小為:
    1. 找出 A[1]A[1] 至 A[n−1]A[n-1] 的最大值。
    2. 再將它與 A[0]A[0] 比較。
  • 必須設定基底條件,避免遞迴無限進行。
  • 每個元素只被比較有限次,因此時間複雜度可達 O(n)O(n)。

題目給定 nn 個元素,假設 n≥1n\geq 1。

解題方法

令 find_max(A, n) 表示找出陣列中前 nn 個元素的最大值。

當 n=1n=1 時,陣列只有 A[0]A[0],最大值就是 A[0]A[0]:

find_max(A,1)=A[0]\text{find\_max}(A,1)=A[0]

當 n>1n>1 時,先遞迴找出 A[1]A[1] 至 A[n−1]A[n-1] 的最大值,再與 A[0]A[0] 比較:

M=find_max(A+1,n−1)M=\text{find\_max}(A+1,n-1)

因此:

find_max(A,n)={A[0],A[0]>MM,A[0]<M\text{find\_max}(A,n)= \begin{cases} A[0], & A[0]>M\\ M, & A[0]<M \end{cases}

因為題目說所有元素互不相同,所以不會發生相等情況;即使允許重複元素,使用 ≥\geq 或 >> 也都能正確找出最大值。

關鍵程式碼

以下以 C 語言風格表示:

int find_max(int A[], int n) {
    if (n == 1) {
        return A[0];
    }

    int max_of_rest = find_max(A + 1, n - 1);

    if (A[0] > max_of_rest) {
        return A[0];
    } else {
        return max_of_rest;
    }
}

呼叫方式:

int answer = find_max(A, n);
🔒

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

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

免費註冊

第 3 題15 分

【此題15分】給定一個陣列A,裡頭包含n個互不相同的整數元素。我們想用最少的 worst
case 執行時間在陣列A裡頭找出前k個最大的元素,其中k遠小於n,例如:k=100、
n = 2¹”。請問用 selection sort、heap sort、quick sort 這三種排序法裡頭的哪一種最合適?
先講答案,然後才針對這三種排序方法作分析。「沒有分析」或「分析錯誤」皆不給分。

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

這一題的完整詳解

【答案】使用 heap sort(以最大堆方式)最合適。

分析

  1. Selection sort

    • 只做 kk 次選擇,每次遍歷整個陣列。
    • 時間 Tsel=O(nk)T_{\text{sel}} = O(nk)。
    • k≪nk\ll n 時仍為線性倍增,對大 nn 不具優勢。
  2. Heap sort(建最大堆)

    • 建堆:O(n)O(n)。
    • 抽出最大值 kk 次,每次 O(log⁡n)O(\log n)。
🔒

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

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

免費註冊

第 4 題15 分

【此題15分】請將下列後序式(postfix) 轉成前序式(prefix),其中A、B、C、D、E、F分別
代表6個互不相同的運算元 (operands)。註:必須寫出推導過程;直接寫答案,此題0分。
DB + FACE+/-*

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

這一題的完整詳解

推導過程

使用堆疊法,由左至右讀取 postfix,遇到運算元直接壓入堆疊,遇到運算子彈出兩個最近的元素,組成 prefix 子式再壓回。

讀入堆疊內容(從底至頂)
DD
BD B
++ D B
F+ D B F
A+ D B F A
C+ D B F A C
🔒

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

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

免費註冊

第 5 題15 分

【此題15分】我們可以用 adjacent matrix 或 adjacency lists 的方式儲存 undirected graph。
給定 undirected graph G,假設G的 vertices數量為n,maximum degree為d,且d遠小於n。
我們想透過 breadth-first search的方式拜訪G裡頭所有的 vertices。那麼用 adjacent matrix 或
adjacency lists 哪一種方式儲存 undirected graph可以有較小的time complexity?先講答案,
然後才提出你的分析。「沒有分析」或「分析錯誤」皆不給分。

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

這一題的完整詳解

**先講答案:**應使用 adjacency lists(鄰接串列),其 BFS 的時間複雜度較小。

核心觀念

設圖 GG 有:

  • nn 個 vertices
  • mm 條 edges
  • maximum degree 為 dd

BFS 的主要工作包含:

  1. 每個 vertex 至多被拜訪、加入佇列一次,成本為 Θ(n)\Theta(n)。
  2. 對每個 vertex 掃描其所有鄰居,成本取決於圖的儲存方式。

對 undirected graph,由握手定理:

∑v∈Vdeg⁡(v)=2m\sum_{v\in V}\deg(v)=2m

又因為每個 vertex 的 degree 不超過 dd:

2m≤nd⟹m≤nd22m\le nd \quad\Longrightarrow\quad m\le \frac{nd}{2}

解題方法與複雜度分析

一、使用 adjacency matrix

Adjacency matrix 是 n×nn\times n 的矩陣。當 BFS 拜訪某個 vertex vv 時,必須掃描矩陣中對應的整列,逐一確認 vv 是否與其他 vertex 相鄰。

每個 vertex 都要掃描 nn 個位置,而共有 nn 個 vertices:

Tmatrix=Θ(n⋅n)=Θ(n2)T_{\text{matrix}}=\Theta(n\cdot n)=\Theta(n^2)

即使某個 vertex 的實際 degree 很小,仍然必須掃完整列,因此 maximum degree 很小也無法降低此方法的主要成本。


二、使用 adjacency lists

Adjacency lists 直接儲存每個 vertex 的鄰居。BFS 拜訪 vertex vv 時,只需掃描 vv 的 adjacency list,不必檢查不存在的 edges。

所有 adjacency lists 的總長度為:

∑v∈Vdeg⁡(v)=2m\sum_{v\in V}\deg(v)=2m

因此,所有鄰居總共只會被掃描 2m2m 次,常數 22 不影響漸近複雜度:

Tlist=Θ(n+m)T_{\text{list}}=\Theta(n+m)
🔒

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

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

免費註冊

第 6 題10 分

【此題10分】假設有n筆key值互不相同的資料,並且n的值很大。我們很在乎搜尋資料
的時間。那麼如何儲存這n筆資料,才能夠讓平均搜尋時間最小?先講答案,
然後才解說你的理由。

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

這一題的完整詳解

答案先講

在一般允許使用雜湊的前提下,應將資料儲存在**雜湊表(hash table)**中,使用分布均勻的雜湊函數,並控制負載因子,使平均搜尋時間達到 Θ(1)\Theta(1)。這是漸近意義下的最佳結果。若 key 值域很小且連續,則可使用直接定址表(direct-address table),搜尋時間甚至可達到 O(1)O(1) 的最壞情況。

核心觀念

這題考的是字典(dictionary)的搜尋效率,以及下列資料結構的時間複雜度:

  • 未排序陣列或鏈結串列:平均 Θ(n)\Theta(n)。
  • 已排序陣列搭配二分搜尋:平均 Θ(log⁡n)\Theta(\log n)。
  • 平衡二元搜尋樹:平均 Θ(log⁡n)\Theta(\log n)。
  • 雜湊表:在雜湊函數良好、碰撞受控制時,平均 Θ(1)\Theta(1)。

雜湊表使用雜湊函數 h(k)h(k) 將 key kk 轉換成表格索引:

h(k)∈{0,1,…,m−1},h(k)\in\{0,1,\ldots,m-1\},

其中 mm 是雜湊表的槽位數。若不同 key 對應到相同槽位,就會發生碰撞(collision)。

令負載因子為

α=nm.\alpha=\frac{n}{m}.

只要維持 α=O(1)\alpha=O(1),每個槽位平均只需處理常數數量的資料。

解題方法與推導

採用分離鏈結(separate chaining)處理碰撞。每個槽位存放一條鏈結串列,將所有具有相同雜湊值的資料放在同一串列中。

在簡單均勻雜湊(simple uniform hashing)的假設下:

  • 不成功搜尋時,預期需要檢查的資料筆數約為
E[Tunsuccessful]=α.E[T_{\text{unsuccessful}}]=\alpha.
  • 成功搜尋時,若每筆資料被搜尋的機率相同,平均檢查筆數約為
🔒

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

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

免費註冊

其他考古題