108 年 國立臺灣聯合大學系統(清華、政治、陽明交通、中央四校聯招)研究所電機類《資料結構》
第 1 題15 分
- (15%) Write a pseudo code for popping data from a stack.
登入後即可作答並保存紀錄。
核心觀念
Stack(堆疊)遵循 後進先出(Last In, First Out, LIFO)原則。push 將資料放入堆疊頂端,pop 則從堆疊頂端取出最近加入的資料。
以陣列實作堆疊時,使用變數 top 記錄頂端元素位置:
top = -1:堆疊為空top >= 0:堆疊非空- 空堆疊執行
pop時發生 underflow(下溢)
解題方法
執行 pop 必須依序完成以下動作:
- 檢查堆疊是否為空。
- 儲存頂端元素。
- 將
top往下移一格。 - 回傳原本的頂端元素。
偽程式碼
假設堆疊以陣列 S[0 ... MAX-1] 表示,且 top 初始值為 :
POP(S, top)
if top == -1 then
report "Stack Underflow"
return ERROR
end if
item ← S[top]
top ← top - 1
return item
若使用需要傳回更新後 top 的寫法,可表示為:
POP(S, top)
if top < 0 then
report "Stack Underflow"
else
item ← S[top]
top ← top - 1
return item
end if
例如堆疊內容為:
第 2 題20 分
- (20%) Given a link list structure as
struct Node
{
int data;
struct Node* next;
};
A list head: struct Node *Head, A particular middle list element struct Node *Mid.
Write a program to delete Mid from the list.
登入後即可作答並保存紀錄。
核心觀念
本題考查單向鏈結串列中,已知某個節點指標時的刪除操作。
每個節點包含:
data:節點資料next:指向下一個節點的指標
若只知道串列首指標 Head,通常需要從頭走訪,找到待刪節點的前一個節點,才能修改前驅節點的 next。
但本題額外給定 Mid,且明確指出它是中間節點,因此 Mid->next 必定存在。可採用以下技巧:
- 將
Mid下一個節點的資料複製到Mid。 - 讓
Mid跳過原本的下一個節點。 - 釋放原本的下一個節點。
如此即可在不知道前驅節點的情況下,刪除 Mid 所代表的串列元素。
解題方法
令:
struct Node *Temp = Mid->next;
原始結構如下:
前一節點 → Mid → Temp → 下一節點
先將 Temp 的資料複製到 Mid:
Mid->data = Temp->data;
此時邏輯上的資料已變成:
前一節點 → Mid(原 Temp 的資料) → Temp → 下一節點
再令:
Mid->next = Temp->next;
結構變成:
前一節點 → Mid(原 Temp 的資料) → 下一節點
最後釋放 Temp:
free(Temp);
原本 Mid 節點的位置仍然存在,但它已經承接下一個節點的資料,因此達成刪除 Mid 所代表元素的效果。
關鍵程式碼
第 3 題20 分
- (20%) Illustrate how data changes while using mergesort to sort:{50 43 51 83 60 33 21} and write down merge sort's time complexity.
登入後即可作答並保存紀錄。
核心觀念
Merge sort(合併排序)採用「分而治之」:
- 將序列遞迴切成兩半。
- 將左右子序列分別排序。
- 以線性時間合併兩個已排序的子序列。
合併時,比較左右兩邊目前最前面的元素,將較小者放入結果序列,直到兩邊元素全部處理完畢。
其遞迴式為:
其中 代表排序左右兩半, 代表合併兩個已排序序列的成本。
解題方法與排序過程
原始序列為:
第一步:遞迴分割
依序切分為:
左半部繼續分割:
右半部繼續分割:
分割至每個子序列只剩一個元素後,開始進行合併。
第二步:合併左半部
先合併:
比較 與 :
再合併:
比較過程:
- 比較 與 ,取出
- 比較 與 ,取出
- 剩餘 ,取出
因此:
第三步:合併右半部
先合併:
因為 ,所以:
再合併:
因為 ,所以:
最後合併:
比較過程:
第 4 題10 分
- (10%) "Block chain" is one of the hottest topic in the information technology. Which calculation algorithm is the core of block chain? Briefly describe this algorithm.
登入後即可作答並保存紀錄。
核心觀念
本題考查區塊鏈的核心密碼學技術:雜湊函數(Hash Function),實務上常以 SHA-256 為代表。
雜湊函數會將任意長度的輸入資料,轉換成固定長度的摘要值:
其中:
- :輸入資料,例如交易紀錄或區塊內容。
- :雜湊函數。
- :固定長度的雜湊值,亦稱摘要或指紋。
以 SHA-256 為例,不論輸入資料大小為何,輸出皆為 位元的雜湊值,通常表示成 位十六進位數字。
解題方法
區塊鏈中的每個區塊通常包含:
- 多筆交易資料;
- 前一個區塊的雜湊值;
- 時間戳記;
- Nonce 等欄位。
目前區塊的雜湊值可表示為:
其中 表示資料串接。
因此,第 個區塊會記錄第 個區塊的雜湊值。若攻擊者修改早期區塊中的任一筆交易資料,該區塊的雜湊值就會改變,後續所有區塊所記錄的前一區塊雜湊值也會不一致,節點即可發現資料遭到竄改。
雜湊函數在區塊鏈中主要提供以下特性:
1. 單向性
由輸入 計算 很容易,但僅由 反推出原始資料 在計算上不可行。
2. 雪崩效應
輸入只要有一個位元改變,輸出的雜湊值就會產生大幅度變化,無法由輸出判斷輸入只做了微小修改。
3. 抗碰撞性
不同輸入產生相同雜湊值的情況稱為碰撞:
良好的密碼學雜湊函數應使尋找碰撞在計算上極為困難。
4. 固定長度輸出
輸入資料可以是任意長度,但輸出摘要長度固定,方便儲存、比對及串接區塊。
與工作量證明的關係
第 5 題20 分
- (20%) Please use recursion to flip(left-right) a binary tree.
登入後即可作答並保存紀錄。
核心觀念
本題要求將二元樹進行左右翻轉(flip left-right),也稱為鏡像(mirror)。
對每一個節點而言,翻轉後必須滿足:
- 原本的左子樹變成右子樹。
- 原本的右子樹變成左子樹。
- 左、右子樹本身也必須繼續進行相同翻轉。
因此,這是一個典型的遞迴問題。其遞迴結構為:
解題方法
設目前節點為 root。
處理順序如下:
- 若
root == NULL,表示已到達空樹,直接返回。 - 遞迴翻轉左子樹。
- 遞迴翻轉右子樹。
- 交換目前節點的
left與right指標。 - 返回翻轉後的樹根。
交換可以使用暫存指標完成:
關鍵程式碼
struct TreeNode {
int data;
TreeNode* left;
TreeNode* right;
};
TreeNode* flip(TreeNode* root) {
if (root == nullptr) {
return nullptr;
}
flip(root->left);
flip(root->right);
TreeNode* temp = root->left;
root->left = root->right;
root->right = temp;
return root;
}
此程式採用原地(in-place)翻轉,不建立新的節點,只調整原有節點的左右子樹指標。
遞迴流程範例
原始二元樹:
A
/ \
B C
/ \ \
D E F
遞迴處理完成後:
第 6 題15 分
- (15%) What's the two common data structure to store Graph ? Compare the pros and cons in using memory between this two data structure.
登入後即可作答並保存紀錄。
核心觀念
圖形(Graph)常見的儲存方式有兩種:
- 鄰接矩陣(Adjacency Matrix)
- 鄰接串列(Adjacency List)
設圖有 個頂點、 條邊。
- 鄰接矩陣以二維陣列表示任兩個頂點之間是否相鄰。
- 鄰接串列為每個頂點建立一條串列,只記錄與該頂點直接相連的頂點。
本題重點是比較兩者的記憶體使用量,並說明圖形稀疏程度對空間效率的影響。
一、鄰接矩陣
定義
建立一個 的矩陣 :
若為加權圖,矩陣元素可直接儲存邊的權重。
記憶體需求
因為矩陣固定有 個位置,所以空間複雜度為:
即使圖中實際只有少量邊,沒有使用到的矩陣位置仍然必須保留,因此鄰接矩陣的空間需求與 無直接關係。
優點
- 判斷兩個頂點是否直接相連非常快速,時間為 。
- 適合邊數很多的稠密圖(dense graph)。
- 矩陣結構簡單,實作容易。
- 進行 Floyd-Warshall 等矩陣型圖形演算法時較方便。
缺點
- 記憶體需求固定為 。
- 對於頂點很多但邊很少的稀疏圖(sparse graph),大量空間只存放不存在的邊。
- 列舉某一頂點的所有鄰居,必須掃描整列,時間為 。
二、鄰接串列
定義
對每個頂點建立一條串列,串列中記錄所有與該頂點相鄰的頂點。
例如,若有邊:
則可表示為:
記憶體需求
首先需要為 個頂點建立串列標頭;每條邊則需要儲存其相鄰資訊。
對於有向圖,每條邊通常記錄一次,因此空間為: