115 年 國立臺灣聯合大學系統(清華、政治、陽明交通、中央四校聯招)研究所電機類《資料結構》
第 1 題
- Given a two-dimensional array A[5][4] (5 rows and 4 columns), assuming it is stored in a "row-major" manner and each element occupies 2 bytes, if the address of A[0][0] is 1000, what is the address of A[2][3]?
(A) 1018
(B) 1022
(C) 1024
(D) 1011
登入後即可作答並保存紀錄。
核心觀念
二維陣列採用 row-major(列優先) 儲存時,同一列的元素會連續存放,索引從 開始。
對於 ,其相對於 的元素位移為:
本題中:
- 每列有 個元素
- 每個元素佔 bytes
- 的位址為
解題方法
要求 的位址。
先計算它前面共有多少個元素:
因此, 位於 後方第 個元素的位置。
換算成 bytes:
所以其記憶體位址為:
選項分析
- (A) 1018:錯誤
bytes,代表位移 個元素,不符合 的位移 個元素。
第 2 題
- What are the main disadvantages of storing a sparse matrix using a general two-dimensional array?
(A) Access speed is too slow
(B) The code is too complex
(C) Wasting a lot of memory space
(D) Matrix multiplication cannot be performed
登入後即可作答並保存紀錄。
核心觀念
稀疏矩陣(sparse matrix)是指矩陣中大部分元素都是 ,非零元素數量 遠小於總元素數量 。
若使用一般二維陣列儲存 的矩陣,必須配置 個儲存格,即使其中大量位置存放的都是 。因此記憶體空間需求為:
稀疏矩陣通常改用三元組(row, column, value)、鏈結串列或其他稀疏結構,只儲存非零元素,使空間需求約為:
因此,一般二維陣列的主要缺點是會浪費大量記憶體空間。
解題方法
判斷各選項是否為「使用一般二維陣列儲存稀疏矩陣」所造成的主要缺點:
- 比較一般二維陣列實際配置的空間。
- 觀察稀疏矩陣中大量的 是否也被儲存。
- 判斷存取與矩陣運算是否仍然可以正常進行。
由於所有 個位置都會配置空間,而其中大部分只是儲存無意義的 ,可知主要問題是空間使用效率低。
選項分析
- (A) Access speed is too slow
第 3 題
- The time complexity of multiplying two matrices using the standard three-loop algorithm is:
(A)
(B)
(C)
(D)
登入後即可作答並保存紀錄。
核心觀念
本題考查矩陣乘法的標準三層迴圈演算法,以及 Big-O 時間複雜度分析。
若有兩個 矩陣 、,其乘積矩陣 的每個元素為:
其中 。因此:
- 共有 個元素。
- 計算每個 時,需要進行 次乘法與加法。
解題方法
標準三層迴圈可表示如下:
for i = 1 to n
for j = 1 to n
C[i][j] = 0
for k = 1 to n
C[i][j] += A[i][k] * B[k][j]
三層迴圈的執行次數為:
內層每次執行只包含固定次數的乘法、加法與指定運算,屬於常數時間 。因此總時間複雜度為:
選項分析
第 4 題
- If we use an array A[0...N-1] to implement a circular queue, and use the variables front and rear, If the condition for a queue to be "empty" is , what is the condition for a queue to be "full"? (To distinguish between empty and full, one space is usually sacrificed.)
(A)
(B)
(C)
(D)
登入後即可作答並保存紀錄。
核心觀念
循環佇列使用陣列 ,索引範圍只有 到 。當指標移動到陣列尾端時,必須透過取模運算回到陣列開頭:
題目定義佇列為空的條件是:
為了區分「空」與「滿」,必須保留一個空格。因此,當 的下一個位置即將追上 時,表示佇列已滿:
解題方法
負責指向佇列尾端之後的下一個可插入位置。每次加入元素後, 向前移動一格:
若移動後 恰好等於 ,代表下一個可插入位置已經碰到佇列前端。此時若再加入元素,就會與「空佇列」的狀態 混淆,因此必須將一格保留不用。
所以佇列已滿的條件為:
例如 時,實際最多只能存放 個元素。若 ,則當 時:
此時佇列為滿。
選項分析
(A)
第 5 題
- Which of the following situations would lead to Stack Overflow?
(A) Try popping data from an empty stack.
(B) The recursion is too deep and there is no convergence condition.
(C) The front of the circular queue caught up with the rear
(D) The number of nodes in the implementation of linked sequences is too small.
登入後即可作答並保存紀錄。
核心觀念
本題考查「Stack Overflow(堆疊溢位)」與其他資料結構錯誤的區別。
堆疊溢位是指:
- 堆疊已無可用空間,仍嘗試進行
push。 - 遞迴呼叫層數過深,耗盡系統用來儲存函式呼叫資訊的執行時期堆疊(call stack)。
相對地,從空堆疊取出資料稱為 Stack Underflow(堆疊下溢),不是 Stack Overflow。
解題方法
逐一判斷各選項描述的錯誤類型,再確認是否屬於「堆疊空間被過度使用」。
遞迴函式每呼叫一次,系統通常會在 call stack 建立一個新的 stack frame,儲存參數、區域變數與返回位置。若遞迴過深,且沒有收斂條件或終止條件,呼叫層數會持續增加:
當可用的 call stack 空間耗盡時,就會發生 Stack Overflow。因此正確選項為 (B)。
選項分析
(A) Try popping data from an empty stack.
從空堆疊執行 pop,代表沒有資料可供取出,這是:
它是堆疊下溢,不是堆疊溢位,因此錯誤。
(B) The recursion is too deep and there is no convergence condition.
遞迴過深且沒有終止條件時,函式會不斷呼叫自身。例如:
第 6 題
- Given an input sequence of 1, 2, 3 (pushed into the stack in that order), which of the following is "not possible" the order in which the elements are popped out?
(A) 3, 2, 1
(B) 1, 2, 3
(C) 2, 3, 1
(D) 3, 1, 2
登入後即可作答並保存紀錄。
核心觀念
堆疊(stack)是後進先出(LIFO)。依序把 1、2、3 推入堆疊,之後每次彈出時,只能取目前最上面的元素。判斷一個輸出順序能不能做到,就是模擬「推入、彈出」的過程,檢查每個要彈出的數字是否已推入,且上方沒有尚未彈出的元素。
解題方法
逐一模擬四個選項:
- 要彈出 x 時,x 必須已經推入,且它上方不能還壓著未彈出的元素。
- 推入順序固定為 1、2、3。若要先彈出較小的數字,比它大的數字必須已先彈出或尚未推入。
選項分析
- (A) 3, 2, 1:全部推入後依序彈出 3、2、1,做得到。
- (B) 1, 2, 3:推 1 後彈出 1,推 2 後彈出 2,推 3 後彈出 3,做得到。
第 7 題
How do we use a stack structure when evaluating postfix expressions (e.g., )?
(A) When encountering an operand, push; when encountering an operator, pop two numbers. Perform the operation on the two numbers and then push the result.
(B) When encountering an operator, use Push; when encountering an operand, use Pop.
(C) Push all operands and operators encountered, and then calculate again at the end.
(D) This requires using columns, not stacks.
登入後即可作答並保存紀錄。
核心觀念
後序運算式(postfix expression)把運算子放在運算元之後,例如 表示 。計算時使用堆疊(stack)暫存尚未完成的運算元:
- 遇到運算元,就推入堆疊。
- 遇到運算子,就依序彈出兩個運算元,計算後把結果推回堆疊。
- 對減法、除法等有順序性的運算,第一次彈出的是右運算元,第二次彈出的是左運算元。
解題方法
題目中的運算式為 。由左至右掃描,堆疊狀態如下;堆疊中的數字以「底部到頂部」排列:
| 讀入項目 | 動作 | 堆疊 |
|---|---|---|
| 推入 | ||
| 推入 | ||
| 彈出 ,計算 ,推入 | ||
| 推入 | ||
| 彈出 ,計算 ,推入 | ||
| 推入 |
第 8 題
If a series of distinct numbers of length are pushed onto a stack in sequence, and can be popped at any time during the process (as long as the stack is not empty), how many different valid permutations can be generated?
(A)
(B)
(C)
(D)
登入後即可作答並保存紀錄。
核心觀念
n 個不同元素依序推入堆疊、過程中可隨時彈出,能產生的不同輸出排列數為卡特蘭數(Catalan number):
解題方法
把「推入」記為向上一步、「彈出」記為向下一步,每一種推入與彈出的操作序列對應一種輸出排列,且一一對應。合法的操作序列要求任何時刻彈出次數都不超過推入次數,也就是路徑不低於起點,這類路徑(Dyck path)的數量正是卡特蘭數。
以 驗算:。3 個元素共有 種排列,其中只有 3, 1, 2 無法由堆疊產生,故剩 5 種。
選項分析
第 9 題
Given a "Perfect Binary Tree" (i.e., every level is full), with a height of (total number of nodes ), compare the worst-case space complexity of using a stack for depth-first search (DFS) versus using a queue for breadth-first search (BFS).
(A) Depth-first search (DFS) is relatively memory-intensive because of its deep recursion depth.
(B) BFS is relatively memory-intensive because a queue needs to store all the leaf nodes at the lowest level.
(C) Both consume roughly the same amount of memory .
(D) Both consume roughly the same amount of memory
登入後即可作答並保存紀錄。
核心觀念
這題比較深度優先搜尋(DFS)與廣度優先搜尋(BFS)在最壞情況下的輔助空間。
完美二元樹每一層都填滿。若根節點位於第 層、高度為 ,則最底層有 個節點,總節點數為
因此 ,而最底層節點數 。
解題方法
DFS 使用堆疊追蹤尚待拜訪的節點。沿著樹往下搜尋時,堆疊主要保留目前路徑及各層尚未拜訪的分支;對二元樹而言,堆疊空間與樹高成正比:
BFS 使用佇列,依層次由上而下拜訪節點。佇列在處理某一層時,會存放下一層中待拜訪的節點;完美二元樹的最底層有 個節點,因此佇列空間可達:
所以相較之下,BFS 在這棵樹上需要較多空間,正確選項是 (B)。
選項分析
第 10 題
Inserting a node named "new" after a node named "p" in a doubly linked list (assuming is not the last node), which of the following four lines of code is in the correct order?
- new->next = p->next;
- p->next->prev = new;
- p->next = new;
- new->prev = p;
(A)
(B)
(C)
(D)
登入後即可作答並保存紀錄。
核心觀念
雙向鏈結串列的每個節點都有 prev 與 next 指標。若原本 的下一個節點是 ,插入前的連結關係為:
要將 new 插入在 與 之間,插入後必須滿足:
因此,四個指標更新的目的分別是:
new->next = p->next;:讓new指向原本的下一個節點 。p->next->prev = new;:讓 的前一個節點改為new。p->next = new;:讓 的下一個節點改為new。new->prev = p;:讓new的前一個節點指向 。
解題方法
關鍵是先保留原本的 p->next。第 3 行會把 p->next 改成 new,所以第 1 行必須在第 3 行之前執行,否則 new->next 會指向自己。第 2 行也必須在第 3 行之前執行,否則它會改到 new->prev,而不是原本後繼節點 的 prev。
符合條件的順序是:
執行後,new->next 指向 、q->prev 指向 new、new->prev 指向 ,最後再令 p->next 指向 new,完成插入。
選項分析
第 11 題
To detect whether a cycle exists in a singly linked list, the most famous Floyd's Cycle Detection Algorithm (the tortoise and the rabbit algorithm) uses two metrics. Assume the distance from the beginning of the linked list to the start of the cycle is , and the length of the cycle is . Assume the rabbit's speed is twice that of the tortoise. When the tortoise and rabbit meet, assume the tortoise has traveled a distance within the cycle. What is the total distance the rabbit has traveled at this point?
(A)
(B)
(C)
(D)
登入後即可作答並保存紀錄。
核心觀念
Floyd 環偵測法使用慢指標(烏龜)與快指標(兔子)同時移動;兔子的速度是烏龜的兩倍。因此,在相同時間內,兔子移動的距離也是烏龜的兩倍。
題目中,烏龜先走過鏈結串列起點至環起點的距離 ,再於環內走過距離 後與兔子相遇。故相遇時烏龜的總行走距離為 。
解題方法
利用兩指標在相遇時經過的時間相同,直接套用距離與速度的比例:
環長 會影響指標相遇的位置關係,但本題已用 表示烏龜在環內走過的距離;計算兔子總距離只需使用兩者的速度比。
選項分析
第 12 題
If we change the rabbit's speed to "3 steps each time" and the tortoise's speed to "1 step each time", can this algorithm still detect the cycle?
(A) No, the rabbit might jump over the tortoise to reach NULL.
(B) Maybe, check if is a multiple of .
(C) Maybe, check if is a multiple of 2.
(D) Perhaps, we can check if and 2 are coprime.
登入後即可作答並保存紀錄。
核心觀念
Floyd 判環法(龜兔賽跑):慢指標(龜)每次走 1 步,快指標(兔)每次走 2 步,若鏈結串列有環,兩者必定相遇。本題改為兔每次走 3 步、龜每次走 1 步。
解題方法
設串列起點到環起點的距離為 、環長為 。龜走了 步、兔走了 步時,若兩者都已進入環(),兔在環內領先龜 步。兩者在同一節點相遇的條件是
取 ( 為使 的正整數)即滿足此式,因此對任何 ,兩者都會在環內相遇。 為偶數時 也滿足,所以偶數環只是較快相遇,並非必要條件。實作上兔每跳一步都要檢查是否為 NULL,才不會對空指標存取。
選項分析
- (A) No, the rabbit might jump over the tortoise to reach NULL:兔追過龜後走到 NULL,只會發生在「無環」的串列。
第 13 題
Skip List is a probabilistic data structure based on linked lists. What is its main purpose in addressing the shortcomings of standard linked lists?
(A) Solving the problem of slow insertion
(B) Solving the problem of not being able to perform fast searches
(C) Solving the problem of excessive memory usage
(D) Solving the problem of being unable to traverse in reverse
登入後即可作答並保存紀錄。
核心觀念
標準單向鏈結串列的搜尋必須從頭節點開始,逐一檢查節點,最壞情況需要走訪 個節點,時間複雜度為 。Skip List(跳躍表)在底層鏈結串列之上增加多層索引,使搜尋時能先跨越多個節點,再逐層縮小範圍。
跳躍表透過隨機方式決定節點出現在多少層,因此其搜尋、插入與刪除的期望時間複雜度皆為 ;其中主要改善標準鏈結串列搜尋效率低的問題。
解題方法
題目問跳躍表的主要用途,因此比較它與標準鏈結串列最明顯的效能差異:標準鏈結串列無法像平衡搜尋樹那樣快速定位資料,搜尋通常需要線性走訪;跳躍表利用多層索引加速搜尋,平均可達對數時間。
因此,題目要找的是「改善快速搜尋能力不足」的選項。
選項分析
- (A) Solving the problem of slow insertion:錯誤。若已知插入位置,標準鏈結串列只需調整指標,插入時間為 。跳躍表也支援期望 的插入,但其主要目的不是解決標準鏈結串列的插入速度問題。
第 14 題
What would be the effect of using the standard "3-Way Partitioning Quick Sort (Dutch National Flag problem)" on an array containing a large number of duplicate keys?
(A) Efficiency became very poor, close to
(B) Extremely efficient, close to
(C) lead to Stack Overflow
(D) No significant difference
登入後即可作答並保存紀錄。
核心觀念
本題考「三向快速排序」(3-Way Quick Sort,也稱 Dutch National Flag partition)如何處理重複鍵值。
選定樞紐值 後,三向分割會把陣列分成三區:
其中「等於 」的區段已完成排序,不再進入遞迴。這是它處理大量重複值的關鍵。
解題方法
若陣列含有大量重複鍵值,分割時會一次把所有等於樞紐值的元素集中到中間,並從後續遞迴中排除。如此可避免反覆比較、分割相同鍵值,遞迴子問題也會縮小。
例如,若所有元素都相同,一趟分割便會把整個陣列歸入「等於樞紐值」區段,工作量為 ,不必再遞迴處理左右子陣列。因此,大量重複值時,三向快速排序通常比一般二向分割的快速排序有效率;
第 15 題
If writing to memory (Write/Swap) is very expensive (e.g., Flash Memory), we want to minimize the number of writes. Which of the following algorithms guarantees the fewest number of writes?
(A) Selection Sort
(B) Cycle Sort
(C) Heap Sort
(D) Quick Sort
登入後即可作答並保存紀錄。
核心觀念
本題考的是排序演算法的寫入次數。若記憶體寫入(Write/Swap)成本很高,應比較各演算法需要改寫多少個陣列位置,而不只比較執行時間。
依一般考題假設,鍵值互異,且「一次寫入」指改寫一個陣列位置。任何排序方法都必須改寫每個錯置的位置,才能使陣列成為排序結果;Cycle Sort(循環排序)會讓每個錯置元素直接移到最終位置,將寫入次數降到最低。
解題方法
將原陣列相對於排序後的陣列分解成若干個循環。若一個循環有 個元素,這 個位置都放錯了,因此至少都要改寫一次。Cycle Sort 逐一找出元素的正確位置,將元素直接放入該位置,完成整個循環時,每個錯置位置只需寫入一次。
所以在上述寫入定義下,最少寫入次數為錯置位置的數量;Cycle Sort 能達到這個下限。它的比較次數可能很多,但本題關注的是寫入成本。
第 16 題
What problems can arise from linear probing?
(A) Primary Clustering
(B) Memory leak
(C) Unable to delete data
(D) Need to perform recursive function call
登入後即可作答並保存紀錄。
核心觀念
線性探測(linear probing)是開放定址法(open addressing)的一種。發生碰撞時,依序檢查下一個位置,直到找到空格為止。
解題方法
逐項判斷各選項是否為線性探測會產生的問題。
選項分析
- (A) Primary Clustering(一次叢聚):已佔用的位置會連成一段,落在該段任一位置的鍵都會延伸同一段,使連續區塊越來越長,探測時間隨之增加。這是線性探測的典型缺點,正確。
第 17 題
If the pre-order of a binary tree is AB D E C F and the in-order is D B E A F C, what is its post-order?
(A) D E B F C A
(B) D E B C F A
(C) E D B F C A
(D) Not Unique
登入後即可作答並保存紀錄。
核心觀念
前序走訪的順序是「根、左子樹、右子樹」;中序走訪的順序是「左子樹、根、右子樹」;後序走訪的順序是「左子樹、右子樹、根」。
已知前序與中序走訪時,可先由前序找出根節點,再用根節點在中序中的位置切分左右子樹,依此遞迴還原二元樹。
解題方法
前序為 ,第一個節點 是整棵樹的根。中序為 ,以 切分後:
- 左子樹的中序為 ,對應前序為 。
- 右子樹的中序為 ,對應前序為 。
左子樹以前序的首節點 為根。在中序 中, 左側是 ,右側是 ,因此左子樹的後序為 。
右子樹以前序的首節點 為根。在中序 中, 位於 左側,沒有右子樹,因此右子樹的後序為 。
第 18 題
Regarding the comparison between Red-Black Trees and AVL Trees, which of the following statements is correct?
(A) AVL trees have more lenient balance conditions than red-black trees, so they can be taller.
(B) Red-black trees guarantee that the longest path from the root to a leaf is no more than twice the length of the shortest path.
(C) In scenarios with a large number of lookups, red-black trees are faster than AVL trees.
(D) In scenarios involving numerous insertions and deletions, AVL trees outperform red-black trees.
登入後即可作答並保存紀錄。
核心觀念
本題比較紅黑樹(Red-Black Tree)與 AVL 樹的平衡條件,以及兩者在查詢與更新時的常見效能取捨。
- AVL 樹:對每個節點,左右子樹高度差的絕對值至多為 ,即平衡因子符合 。平衡條件嚴格,樹高通常較低。
- 紅黑樹:每個節點標為紅色或黑色,並遵守紅黑性質,例如根為黑色、紅節點的子節點必為黑色,以及從任一節點到其後代葉節點的每條路徑含有相同數目的黑色節點。條件較寬鬆,允許樹高相對較高。
兩種樹的查詢、插入與刪除在最壞情況下皆為 。實際使用時,AVL 樹較低的樹高通常有利於查詢;紅黑樹的更新平衡成本通常較低,常見實作中旋轉次數也較少。
解題方法
逐一檢查各選項的敘述:
- 由平衡條件比較樹高:AVL 條件較嚴格,紅黑樹較寬鬆。
- 用紅黑樹的黑高性質推導最長路徑與最短路徑的關係。
- 比較查詢與更新時,分清楚「樹高」與「維持平衡所需的成本」。
對紅黑樹而言,令任一根到葉節點路徑上的黑色節點數為 。所有這類路徑的黑色節點數相同。由於紅色節點不能相鄰,路徑上的紅色節點數至多為 ,所以最長路徑長度至多為 。
第 19 題
2-3 Tree is a special type of B-Tree. What conditions must all its leaf nodes satisfy?
(A) In the Same level
(B) It must contain 3 key-value pairs.
(C) In different level only and .
(D) Must be filled from left to right
登入後即可作答並保存紀錄。
核心觀念
2-3 樹是一種平衡的 B 樹。每個內部節點有 2 個或 3 個子節點;每個節點存放 1 個或 2 個鍵值。它的平衡條件是:所有葉節點都位於同一層,也就是從根節點走到任一葉節點,路徑長度相同。
解題方法
題目問的是 2-3 樹「所有葉節點必須滿足的條件」。直接對照其平衡條件即可:葉節點的層數必須一致,因此選項 (A) 正確。
選項分析
- (A) In the Same level:正確。 所有葉節點都在同一層,這是 2-3 樹維持平衡的核心條件。
- **(B) It must contain 3 key-value pairs:錯誤。
第 20 題
Which of the following comparisons between BST and Heap is incorrect?
(A) In-order traversal of a BST is ordered, while that of a Heap is not.
(B) The time complexity of searching for any value in the Heap is .
(C) A heap is a complete binary tree, while a BST is not.
(D) Heaps are typically implemented using arrays, while BSTs are typically implemented using pointers.
登入後即可作答並保存紀錄。
核心觀念
這題比較二元搜尋樹(BST)與堆積(Heap)的排序性質、搜尋效率、樹形限制與常見實作方式。
BST 的左子樹鍵值小於根節點、右子樹鍵值大於根節點;因此其中序走訪會依鍵值排序。堆積只要求父節點與子節點符合堆積順序:最小堆中,父節點不大於子節點;最大堆中,父節點不小於子節點。堆積並不要求同一層或左右子樹之間有完整的排序關係。
解題方法
逐項檢查選項中的性質是否由資料結構定義保證,特別注意「搜尋任意值」是否能利用堆積的局部順序快速排除大量節點。
堆積只能保證根節點是全體最小值或最大值,不能像 BST 一樣依搜尋值決定只往左子樹或右子樹走。因此,搜尋任意值在最壞情況下必須檢查所有節點,時間複雜度為 ,不是 。
選項分析
(A) 正確。 BST 的中序走訪會依鍵值遞增排列。堆積只限制父子節點的大小關係,不保證中序走訪結果有序。
第 21 題
Suppose that we have a Binary Search Tree (BST) consisting of nodes, where each node stores a unique integer between 1 and 1000. Which of the following sequences could be a VALID sequence of nodes examined when searching for the number 101?
(A) 80, 252, 90, 130, 110, 100, 120, 101
(B) 252, 130, 120, 110, 100, 90, 80, 101
(C) 80, 90, 252, 110, 130, 120, 100, 101
(D) 80, 252, 90, 100, 130, 120, 110, 101
(E) 252, 130, 110, 80, 90, 100, 120, 101
登入後即可作答並保存紀錄。
核心觀念
在二元搜尋樹(BST)中搜尋目標值 時:
- 若目前節點值小於 ,下一步必須往右子樹,並提高搜尋路徑的下界。
- 若目前節點值大於 ,下一步必須往左子樹,並降低搜尋路徑的上界。
- 搜尋路徑上的每個節點,都必須符合先前比較所累積的上下界;節點值唯一,因此界限採嚴格不等式。
因此,可以用一個開區間 記錄目前節點必須落在的範圍。初始範圍為 。
解題方法
逐一檢查每個選項:依照節點值與 的大小更新上下界,再確認下一個節點是否仍落在更新後的區間。若某節點違反上下界,該搜尋路徑就不可能出現在 BST 中。
選項分析
(A) 80, 252, 90, 130, 110, 100, 120, 101:錯誤
搜尋到 時,先前的路徑包含 ,且 ,所以搜尋必須從 往左。此時 位於 的左子樹,下一步往右後,節點值必須大於 、小於 。但下一個節點是 ,違反上界 。
(B) 252, 130, 120, 110, 100, 90, 80, 101:錯誤
搜尋到 時,因為 ,下一步必須往右,後續節點值必須大於 。但下一個節點是 ,小於 ,不可能是搜尋路徑上的下一個節點。
第 22 題
Height: Assume that the height of a tree node is the number of edges on the longest path from the node to a leaf. A leaf node will have a height of 0.
Balance: The balance of a binary tree node is defined as the left child node's height minus the right child node's height. The balance of a leaf node is 0 (since the height of a NULL child node is defined as -1).
What is the height of the root of a Binary Search Tree (BST) after inserting 5, 3, 9, 2, 4, 7, 1, 6, 10, 8? The tree is empty initially.
(A) 3
(B) 4
(C) 5
(D) 6
(E) 7
登入後即可作答並保存紀錄。
核心觀念
本題考查二元搜尋樹(BST)的插入規則,以及樹高的定義。BST 插入時,較小的鍵值放在左子樹,較大的鍵值放在右子樹。
節點的高度是從該節點到最遠葉節點的路徑所含的邊數。葉節點高度為 ,因此:
題目提供的平衡值定義與求根節點高度無關;只需依序建立 BST,再計算最長根到葉路徑的邊數。
解題方法
依序插入 ,比較每個新鍵值與目前節點的大小,決定向左或向右:
- 成為根節點。
- ,放在 的左側;,放在右側。
- 且 ,放在 的左側; 且 ,放在 的右側。
- 且 ,放在 的左側;、、,放在 的左側。
- 、、,放在 的左側; 且 ,放在 的右側;、、,放在 的右側。
第 23 題
What is the balance of the root of a Binary Search Tree (BST) after inserting 5, 3, 9, 2, 4, 7, 1, 6, 10, 8? The tree is empty initially.
(A) -2
(B) -1
(C) 0
(D) 1
(E) 2
登入後即可作答並保存紀錄。
核心觀念
二元搜尋樹(BST)插入時,小於目前節點的鍵值往左子樹搜尋,大於目前節點的鍵值往右子樹搜尋。
節點的平衡因子定義為左子樹高度減右子樹高度:
本題採用葉節點高度為 、空子樹高度為 的定義。要求的是根節點的平衡因子,不是整棵樹是否為 AVL 樹。
解題方法
依序插入 ,得到下列 BST:
5
/ \
3 9
/ \ / \
2 4 7 10
/ / \
1 6 8
根節點 的左子樹根為 ,右子樹根為 。
左子樹中,節點 的高度為 ,節點 的高度為 ,因此:
第 24 題
If you want to find the top 100 students by scanning a list of scores, which of the following data structures will offer the best computational time?
(A) min-heap sized 100
(B) max-heap sized 100
(C) balanced binary search tree such as AVL-tree with 100 nodes
(D) sorted linked list sized 100
(E) sorted array sized 100
登入後即可作答並保存紀錄。
核心觀念
這題考查如何在掃描分數串列時,持續保留最高的 個分數。令總分數筆數為 ,保留筆數為 。
要快速判斷新分數是否值得保留,關鍵是能否快速找到目前前 名中最低的分數。若新分數不高於這個門檻,就直接略過;若高於門檻,就以新分數取代門檻分數。
最小堆的堆頂正是堆中最小值,因此能直接取得目前前 名的最低分。
解題方法
先用前 筆分數建立一個容量為 的最小堆。之後逐筆掃描剩餘分數:
- 若新分數不高於堆頂,略過。
- 若新分數高於堆頂,以新分數取代堆頂,再調整堆,使最小值回到堆頂。
每筆分數只需與堆頂比較一次;需要取代時,再花 調整堆。因此總時間為
其中 。空間複雜度為 。
選項分析
(A) min-heap sized 100:正確。
堆頂直接提供目前前 名中的最低分。新分數若高於堆頂,只需取代堆頂並調整堆,操作時間為 ;若未高於堆頂,則只需 比較。這是最適合維護前 名的結構。
第 25 題
To find the top 100 words by appearance frequency in a book, which of the following data structures will offer the best computational time for counting the word frequency?
(A) list of linked lists
(B) queue
(C) tree
(D) array
(E) hash table
登入後即可作答並保存紀錄。
核心觀念
本題考查用資料結構統計文字中各單字的出現次數。若書中共有 個單字,且不同單字共有 種,統計時需要反覆查詢單字是否已出現:若出現過,就將其計數加一;若未出現,就新增單字並將計數設為一。
雜湊表查詢與更新的平均時間為 ,因此掃描全文計算詞頻的平均時間為 ,空間需求為 。
解題方法
原卷第 25 題詢問:要找出書中出現頻率最高的 100 個單字,哪種資料結構能讓「計算單字頻率」所需的運算時間最佳;選項依序為鏈結串列的串列、佇列、樹、陣列、雜湊表。關鍵在題目指定的是計算詞頻:每讀到一個單字,都要快速查找並更新該單字的計數,因此適合使用平均查找與更新時間為 的雜湊表。
選項分析
- (A) list of linked lists:錯誤。 若以鏈結串列搜尋單字,每次查找都可能需要逐一檢查節點,最壞需 ;掃描全文的最壞時間可達 。
第 26 題
Which of the following traversal methods takes a Breadth-First search (BFS) approach?
(A) pre-order traversal
(B) in-order traversal
(C) post-order traversal
(D) level-order traversal
(E) None of the above
登入後即可作答並保存紀錄。
核心觀念
廣度優先搜尋(BFS)會先拜訪距離起點較近的節點,再逐層向外探索。在樹中,這種拜訪順序稱為層序走訪(level-order traversal),通常使用佇列來維持待拜訪節點的先後順序。
前序、中序與後序走訪則都是深度優先搜尋(DFS)的走訪方式:沿著樹的分支深入,再回頭處理其他分支。
解題方法
依原卷圖中第 26 題,題目詢問哪一種走訪方法採用 BFS;選項依序為前序、中序、後序、層序,以及「以上皆非」。判斷關鍵是看走訪順序:若按照每一層由上而下拜訪,就是 BFS。
選項分析
第 27 題
Which of the following arrays is NOT a valid Max-Heap or Min-Heap?
(A) int A[]={10,7,9,4,1};
(B) int A[]={16,14,9,2,4,1,8,3};
(C) int A[]={25,20,24,10,15,20,8,5};
(D) int A[]={50,45,30,15,20,10};
(E) int A[]={3,6,4,10,7,9};
登入後即可作答並保存紀錄。
核心觀念
陣列表示的二元堆積,其索引採 起算時,索引 的左、右子節點分別位於 與 。堆積必須符合以下其中一種順序性質:
- Max-Heap(最大堆積):每個父節點的鍵值都大於或等於子節點。
- Min-Heap(最小堆積):每個父節點的鍵值都小於或等於子節點。
題目給定的陣列依序填入完全二元樹,因此只要檢查父子節點的大小關係,判斷是否能符合最大堆積或最小堆積即可。
解題方法
逐一檢查各選項中每個父節點與子節點的關係。某個陣列只要能符合最大堆積或最小堆積其中一種性質,就算是有效堆積;若兩種都不符合,便是題目所問的無效陣列。
選項分析
(A)
以 為根,子節點為 、; 的子節點為 、。各父節點都大於或等於子節點,因此符合 Max-Heap,為有效堆積。
(B)
索引 的父節點為 ,其子節點為 、;索引 的節點為 ,索引 的節點為 。因為 ,違反 Max-Heap 的父節點不小於子節點條件。
Answer Questions 28-30 according to the following C code.
1 #include <stdio.h>
2 #include <stdlib.h>
3 int counter=0;
4 void max_heapify(int A[],int n,int i) {
5 int largest=i;
6 int left=2i+1;
7 int right=2i+2;
8 counter++;
9 if (left<n && A[left]>A[i])
10 largest=left;
11 if (right<n && A[right]>A[largest])
12 largest=right;
13 if (largest!=i) {
14 int temp=A[i];
15 A[i]=A[largest];
16 A[largest]=temp;
17 max_heapify(A,n,largest);
18 }
19 }
20 void build_heap(int A[],int n) {
21 for (int i = (n/2)-1;i>=0;i--)
22 max_heapify(A,n,i);
23 }
24 int main(){
25 int A[]={4,1,3,2,16,9,10,14,8,7};
26 int n = sizeof(A)/sizeof(A[0]);
27 build_heap(A,n);
28 for (int i=0;i<n;++i)
29 printf("%d,",A[i]);
30 printf("\n");
31 printf("counter:%d\n",counter);
32 return 0;
33 }
第 28 題
What does the for-loop between Lines 28 and 29 print?
(A) 4,1,3,2,16,9,10,14,8,7,
(B) 16,14,10,8,7,9,3,2,4,1,
(C) 1,2,3,4,7,8,9,10,14,16,
(D) 16,14,10,8,7,3,9,1,4,2,
(E) 16,14,10,9,8,7,4,3,2,1,
登入後即可作答並保存紀錄。
核心觀念
這題考「最大堆積」與自底向上建堆。最大堆積是一棵完全二元樹,且每個父節點的值都不小於其子節點。陣列採用從 開始的索引時,索引 的左右子節點分別是 與 。
build_heap 從最後一個非葉節點 開始,逐一向根節點呼叫 max_heapify。這會將陣列重新排列成最大堆積,但不會把元素整體排序。
解題方法
本題有 個元素,因此建堆從索引 開始,依序處理 。每次處理時,若父節點小於較大的子節點,就交換,並沿交換後的子樹繼續調整。
| 處理索引 | 調整後的陣列 |
|---|---|
以索引 為例,其子節點在索引 、,值為 、。將 與 交換後,索引 的子節點值為 ,再將 與 交換。完成全部建堆後,程式在第 28、29 行依索引順序印出:
16,14,10,8,7,9,3,2,4,1,
關鍵程式結構如下:
第 29 題
What does the code at Line 31 print? Counter : ____
(A) 6
(B) 10
(C) 12
(D) 14
(E) 16
登入後即可作答並保存紀錄。
核心觀念
counter 在 max_heapify 一進入函式時就加 。因此它計算的是 max_heapify 的呼叫次數,包含 build_heap 直接呼叫的次數,以及發生交換後的遞迴呼叫次數;不只是交換次數,也不只是外層迴圈的次數。
build_heap 從最後一個非葉節點開始,由後往前呼叫 max_heapify。對 ,起始索引為 ,所以外層呼叫索引依序為 。
解題方法
每次進入 max_heapify,counter 加 。若節點需要和較大的子節點交換,便沿著交換後的位置遞迴呼叫;遞迴到不需交換或抵達葉節點才停止。
| 起始索引 | 遞迴呼叫索引 | 呼叫次數 |
|---|---|---|
| 4 | 4 | 1 |
| 3 | 3 → 7 | 2 |
| 2 | 2 → 6 | 2 |
| 1 | 1 → 4 → 9 | 3 |
| 0 | 0 → 1 → 3 → 8 | 4 |
第 30 題
What is the computational complexity of build_heap()?
(A)
(B)
(C)
(D)
(E)
登入後即可作答並保存紀錄。
核心觀念
build_heap() 使用自底向上的方式建立最大堆積:從最後一個非葉節點開始,依序對每個節點呼叫 max_heapify()。雖然單次 max_heapify() 的最壞時間是 ,但各節點需要向下調整的高度不同,因此不能直接將所有呼叫都視為花費 。
解題方法
程式從索引 遞減至 ,總共呼叫約 次 max_heapify()。分析時依節點高度分組:
- 高度為 的節點至多約有 個。
- 每個高度為 的節點,至多向下調整 層,花費 。
因此,所有節點的總工作量上界為:
最後的級數收斂至常數,因此 build_heap() 的時間複雜度為 。此方法確實處理線性數量的節點,故緊確複雜度為 。
第 31 題
Given a graph where vertices and Edges . represents a directed edge from vertex to vertex . Which of the following does NOT form a Directed Acyclic Graph (DAG)?
(A)
(B)
(C)
(D)
(E)
登入後即可作答並保存紀錄。
核心觀念
有向無環圖(DAG)是不含任何有向環的有向圖。判斷圖是否為 DAG,可檢查是否存在一條沿著箭頭方向走、最後回到起點的路徑;也可確認圖是否存在拓樸排序。若存在拓樸排序,圖中就沒有有向環。
解題方法
依原卷圖,頂點為 ,各選項列出六條有向邊; 表示箭頭由 指向 。逐一檢查選項中的邊,找出是否能沿箭頭方向回到原頂點。
選項分析
(A) 不形成 DAG,為本題答案。
選項中的邊包含 、、、,可連成有向環:
因此此圖有有向環,不是 DAG。
(B) 形成 DAG。
邊的方向都符合以下順序:。例如 、、、,其餘邊 、 也都由前面的頂點指向後面的頂點,
第 32 題
The adjacency-matrix representation of a graph assumes that the vertices are numbered . Then the adjacency-matrix representation of a graph consists of a matrix such that
Let and its adjacency matrix be
| 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|
| 1 | 0 | 1 | 0 | 1 | 0 |
| 2 | 0 | 0 | 0 | 0 | 1 |
| 3 | 0 | 0 | 0 | 0 | 1 |
| 4 | 0 | 1 | 0 | 0 | 0 |
| 5 | 0 | 0 | 0 | 1 | 0 |
Which of the following descriptions is WRONG or the least accurate?
(A)
(B) The graph is a directed acyclic graph
(C) The graph has 5 vertices
(D) The graph has 6 edges
(E) There is no path that can go from vertex 1 to vertex 3
登入後即可作答並保存紀錄。
核心觀念
有向圖的鄰接矩陣中, 表示存在一條由頂點 指向頂點 的邊。矩陣第 列列出頂點 的所有出邊;全矩陣中 的總數就是邊數。
有向無環圖(DAG)是指不含任何有向環的有向圖。判斷是否為 DAG,關鍵是找出是否存在沿著邊方向回到原頂點的路徑。
解題方法
依照題目附圖中的矩陣讀取各列的 ,得到邊集合:
其中可看出 、、,因此形成有向環:
所以此圖不是有向無環圖。再核對各選項:矩陣有 列與 欄,因此有 個頂點;矩陣共有 個 ,因此有 條邊。
第 33 題
In graph theory an undirected graph has two kinds of incidence matrices: unoriented and oriented. The unoriented incidence matrix of an undirected graph is an matrix , where and are the number of vertices and edges respectively, such that
An undirected graph (with no self-loops) consisting of 4 nodes and 4 edges is given as followed:
🖼️【此處有附圖,請對照原卷】
The incidence matrix of the undirected graph above is (: , : , etc.):
| 1 | 1 | 1 | 1 | 0 |
| 2 | 1 | 0 | 0 | 0 |
| 3 | 0 | 1 | 0 | 1 |
| 4 | 0 | 0 | 1 | 1 |
The incidence matrix of a directed graph is an matrix such that
The oriented incidence matrix of an undirected graph is the incidence matrix of ANY orientation of the graph. Check the following oriented incidence matrices of the given graph with ANY chosen edge direction. Which of the following matrix with the multiplication: (T: transpose) will generate a result that is different from the others?
(A)
(B)
(C)
(D)
(E) All of the above generate the same results
登入後即可作答並保存紀錄。
核心觀念
有向關聯矩陣的每一欄對應一條邊,兩個端點分別填入 與 。反轉一條邊的方向,只會讓該欄整欄乘上 。
若將矩陣 的各欄分別乘上 或 ,可寫成 ,其中 是對角元素為 或 的對角矩陣。由於 ,
因此,邊的方向不影響 的結果。
解題方法
依原卷圖,四條邊依序為 、、、。比較各選項時,只要確認每欄是否在對應邊的兩個端點各有一個 和一個 ;若符合,各矩陣僅在邊方向上有所不同,乘上轉置後便會得到相同結果。
以選項 (A) 為例,其各列向量為
的第 項是第 列與第 列的內積。因此,
第 34 題
The following is an oriented incidence matrix with another orientation setting. What is the result of the multiplication: (T: transpose)
(A)
(B)
(C)
(D)
(E)
登入後即可作答並保存紀錄。
核心觀念
矩陣 的第 項,是 的第 列與第 列的內積:
因此,對角線元素是各列與自身的內積;非對角線元素則是不同列之間的內積。此題也可從圖的關聯矩陣觀察:每列的對角線元素反映該頂點連接的邊數,非對角線元素反映兩頂點是否由同一條邊連接及其方向符號。
解題方法
設 的四列依序為
先算各列與自身的內積:
再計算不同列之間的內積:
第 35 題
Let matrices and represent the Adjacency and Degree matrices of an undirected graph ( vertices, edges) with no self-loops. Let be an oriented incidence matrix of the same undirected graph. What is the relationship of , , and ? ( is the diagonal matrix of vertex degree (), where the entries is the degree of vertex , the number of edges incident to it).
(A)
(B)
(C)
(D)
(E)
登入後即可作答並保存紀錄。
核心觀念
有向關聯矩陣(oriented incidence matrix) 用來表示頂點與邊的關係。依慣例, 的列對應頂點、行對應邊,因此 的大小為 。每條邊所在的欄有兩個非零值:一端為 ,另一端為 ;正負方向依邊的定向而定。
圖中的第 35 題給定無自環的無向圖,並將 定義為鄰接矩陣、 定義為頂點度數對角矩陣。第 12 頁列出選項;沒有額外的個別圖形或數值需要代入。
解題方法
計算 的矩陣元素。對角元素 是頂點 對應列的平方和:每條連到頂點 的邊都貢獻 ,所以總和等於頂點 的度數 。
非對角元素 是頂點 與頂點 對應列的內積。若 、 之間有一條邊,該邊在兩端的值一正一負,貢獻 ;沒有邊則貢獻 。因此:
這正是度數矩陣減去鄰接矩陣:
第 36 題
Which of the following C functions/macros are valid codes to swap two int variables?
M1.
#define SWAP(type,a,b) {type temp=a;a=b;b=temp;}
//SWAP(int,a,b)
M2.
#define SWAP(a,b) (a+=b,b=a-b,a-=b)
//SWAP(a,b);
F3.
void swap(int* a, int* b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}
//int x,y; swap(&x,&y);
F4.
void swap(int* a, int* b) {
*a = *b;
*b = *a;
}
//int x,y; swap(&x,&y);
F5.
void swap(int a, int b) {
int temp;
temp = a;
a = b;
b = temp;
Return;
}
//int x,y; swap(x,y);
(A) M1 and M2 only
(B) F3 only
(C) M2 and F3
(D) M1, M2, and F3
(E) All
登入後即可作答並保存紀錄。
核心觀念
交換兩個整數,必須讓原本的兩個值都保留下來,並且改變呼叫端的變數。這題主要考:
- 巨集展開:巨集會在編譯前展開成程式碼。
- 指標與呼叫端變數:函式若要改變呼叫端的變數,需透過指標存取該變數。
- 值呼叫:C 函式的參數預設是值呼叫;函式內修改參數副本,不會改變呼叫端變數。
- 整數溢位:有號整數運算若超出可表示範圍,會造成未定義行為。
解題方法
逐一檢查各段程式是否能正確交換呼叫端兩個整數的值:
- 有沒有保留交換前的值?
- 函式是否透過指標修改呼叫端變數?
- 巨集展開後是否是有效的交換程式?
- 是否有整數溢位或語法錯誤?
以下依一般考題慣例判斷 M2,假設中間的整數加法不會溢位。
選項分析
-
M1:有效。
呼叫SWAP(int,a,b)後會展開為:{ int temp = a; a = b; b = temp; }暫存變數
temp保留a的原值,再把b指派給a,最後將原本的a指派給b,因此完成交換。此巨集適用於題目所示的一般變數引數。 -
M2:依一般考題假設有效。
設初值為a=A、b=B,依序執行:最後得到
a=B、b=A。不過,若A+B超出int可表示範圍,C 的有號整數溢位會造成未定義行為;因此它不是對所有int值都安全的交換寫法。
第 37 題
A magic square is an matrix of the integers from 1 to such that the sum of each row and column and the two major diagonals is the same. The following figure shows a magic square for the case where the common sum is 65.
15 8 1 24 17
16 14 7 5 23
22 20 13 6 4
3 21 19 12 10
9 2 25 18 11
Coxeter has given the following rule for generating a magic square when is odd:
- Put a one (// 1.) in the middle box of the top row.
- Go up (// 2.1) and left (// 2.2) assigning numbers in increasing order to empty boxes. If your move causes you to jump off the square (that is, you go beyond the square's boundaries), figure out where you would be if you landed on a box on the opposite side of the square. Continue with this box.
- If a box is occupied (// 3.1), go down (// 3.2) instead of up and continue.
1 square[0][(n-1)/2]=1; // 1. Top row [0]; middle box [(n-1)/2]
2 /* i and j are current position */
3 i=0;
4 j=(n-1)/2;
5 for (count=2;count<=n*n;count++) {
6 row=(i-1<0)?(n-1):(i-1); // 2.1 up
7 column=(j-1<0)?(n-1):(j-1); // 2.2 left
8 if(square[row][column]) // 3.1 occupied
9 i=(++i)%n; // 3.2 down
10 else{
11 i=_______ ; // 3.3 _______
12 j=(j-1<0)?(n-1):--j;
13 }
14 square[i][j]=count;
15 }
Fill the blank i=_______; with correct code at the location annotated by //3.3.
(A) n
(B) row
(C) column
(D) count
(E) i%n
登入後即可作答並保存紀錄。
核心觀念
這是奇數階魔方的 Siamese(de la Loubère)填法:從最上列中間放 1,之後每次斜向「上、左」移動填入下一個數;超出邊界就繞到對側(環狀);遇到已填的格子時,改為往下移一格。本題要判斷的是未佔用分支(第 11 行,3.3)要填什麼。
解題方法
程式的兩個分支如下:
- 若目標格
square[row][column]已被佔用,執行 3.2:i=(++i)%n;,列往下移一格,欄j不變,也就是目前格子的正下方。 - 若目標格未被佔用,執行 3.3 與下一行:先把列設為
row(第 6 行已算好的上一列,越界時已繞到底列),再以j=(j-1<0)?(n-1):--j;把欄設為左一欄。
因此 3.3 要填 row,即 i=row;。row 已在前面計算完成,不能寫 i 本身,否則列不會往上移。
選項分析
第 38 題
Given a set of elements (), the following code prints out all possible permutations of this set. For example, if the set is {a, b, c}, then the set of permutation is {(a, b, c), (a, c, b), (b, a, c), (b, c, a), (c, b, a), (c, a, b)}.
#include <stdio.h>
#include <string.h>
#define SWAP(A, B) do { char _tmp[sizeof((A))]; \
memcpy(_tmp,&(A),sizeof((A))); \
(A)=(B); \
memcpy(&(B),_tmp,sizeof((B)));} while(0)
void perm(char *list, int i, int n) {
int j, temp;
if(i==n){
for(j=0;j<=n;j++)
printf("%c",list[j]);
printf(",");
}
else {
for (j=i;j<=n;j++){
SWAP(list[i],list[j]);
printf("%d%d,",i,j); //swap i,j
perm(list,i+1,n);
printf("%d%d,",j,i); //swap j,i
SWAP(list[j],list[i]);
}
}
}
int main(){
char str[]="abc";
perm(str,0,2);
return 0;
}
What will the code print?
(A) 00,11,abc,11,22,acb,22,00,01,11,bac,11,22,bca,22,10,02,11,cba,11,22,cab,22,20,
(B) 00,12,abc,21,11,acb,11,00,01,12,bac,21,11,bca,11,10,02,12,cba,21,11,cab,11,20,
(C) 00,01,abc,10,12,acb,21,00,01,01,bac,10,12,bca,21,10,02,01,cba,10,12,cab,21,20,
(D) 00,11,abc,11,12,acb,21,00,01,11,bac,11,12,bca,21,10,02,11,cba,11,12,cab,21,20,
(E) 00,11,abc,11,12,acb,21,00,10,11,bac,11,12,bca,21,01,20,11,cba,11,12,cab,21,02,
登入後即可作答並保存紀錄。
核心觀念
這是以「交換、遞迴、還原」產生全排列的回溯法(backtracking)。perm(list, i, n) 負責排列 list[i..n]:每個位置 i 依序與 j = i..n 的字元交換,對下一個位置遞迴,回來後再交換還原。
解題方法
程式的印出分為兩類:
- 每次交換後印
i j,,遞迴返回後印j i,。兩者成對出現,因此每個交換都會留下一組數字。 - 當
i==n時為葉節點,印出list[0..n]共 n+1 個字元,再印一個逗號。以 n=2 為例,葉節點依序印出 abc、acb、bac、bca、cba、cab,即六種排列。
以 str="abc"、perm(str,0,2) 追蹤前幾步:
i=0, j=0:交換不變,印00,,進入perm(1)。perm(1)的j=1:印11,,進入perm(2)印出abc,,返回後印11,。perm(1)的j=2:交換得acb,印12,,葉節點印出acb,,返回印21,並還原為abc。- 回到
perm(0)後印00,,接著j=1:交換得bac,印01,,依此類推。
完整輸出為:
第 39 題
The following piece of code is a version of Insertion Sort Algorithm that works on data stored in an array. Please read the following code and find which description given in (A) to (E) is WRONG or the least accurate statement?
void insertionSort1(int arr[], int n) {
for(int i=0; i<n; ++i) {
int key=arr[i];
int j=i-1;
while(j>=0 && arr[j]>key){
arr[j+1]=arr[j];
j=j-1;
}
arr[j+1]=key;
}
}
(A) It is in-place.
(B) It is stable.
(C) Computation complexity is .
(D) The number of comparisons can be reduced with binary search.
(E) The sequential search of insertion locations can be improved if a linked list is implemented.
登入後即可作答並保存紀錄。
核心觀念
插入排序(insertion sort)是把每個元素 key 插入到前面已排好的部分。程式以 while 由右向左比較,把大於 key 的元素向後位移,再將 key 放入空出的位置。
解題方法
逐項對照程式的實際行為與演算法理論,找出錯誤或最不精確的敘述。
選項分析
- (A) In-place:只使用
key、i、j等固定數量的變數,不需額外陣列,正確。 - (B) Stable:只有
arr[j] > key時才位移,相等的元素不會越過彼此,相同值的相對順序保持不變,正確。
第 40 題
The following piece of code is a version of Insertion Sort Algorithm that used a linked list to store the sorted data. Fill in the two blank areas on Lines 14 and 20 to make the insert() function maintain the list as a sorted list in ascending order. Nodes with equal values (val) must be ordered according to their insertion time (the earlier ones are placed before the later ones).
1 #include <stdio.h>
2 #include <stdlib.h>
3 struct Node {
4 int val;
5 struct Node* next;
6 };
7 struct Node* createNode(int x) {
8 struct Node* node = (struct Node*)malloc(sizeof(struct Node));
9 node->val = x;
10 node->next = NULL;
11 return node;
12 }
13 struct Node* insert(struct Node* head,struct Node* item){
14 if(head==NULL || head->val ____ item->val){
15 item->next=head;
16 head=item;
17 }
18 else {
19 struct Node* curr=head;
20 while(curr->next != NULL && curr->next->val ____ item->val) {
21 curr=curr->next;
22 }
23 item->next=curr->next;
24 curr->next=item;
25 }
26 return head;
27 }
(A) Line 14: >, Line 20: <=
(B) Line 14: >, Line 20: <
(C) Line 14: <, Line 20: <=
(D) Line 14: <, Line 20: >=
(E) Line 14: >=, Line 20: <
登入後即可作答並保存紀錄。
核心觀念
這是以鏈結串列實作的插入排序。insert() 把新節點插入已排序的串列,要求升冪排列,且相等值依插入先後排序(先插入者在前)。
解題方法
- 第 14 行(是否插在最前面):若串列為空,或
head->val大於新節點的值,新節點就插在最前面。若兩者相等,新節點必須排在既有節點之後,因此必須用嚴格的>。 - 第 20 行(向後走的條件):只要
curr->next->val不大於新節點的值,就繼續往後走,停在第一個大於新值的節點之前。因此應使用<=,讓相等的既有節點留在新節點之前。
例:串列為 3(a)、3(b),插入 3(c)。第 14 行 3 > 3 不成立,進入 else;第 20 行 3 <= 3 成立,移到 3(b),之後 next 為 NULL,因此接在 3(b) 之後,結果為 3(a)、3(b)、3(c)。
選項分析
Answer Questions 41-43 according to the following C code.
1 #include <stdio.h>
2 int counter; // counting comparison
3 int binary_search(int arr[], int key, int left, int right) {
4 int mid;
5 if(left>right){
6 counter++;
7 return left;
8 }
9 if (key<arr[left]){ //left boundary
10 counter++;
11 return left;
12 }
13 if (key>=arr[right]){ //right boundary
14 counter++;
15 return right+1;
16 }
17 mid=(left+right)/2;
18 if (key<arr[mid].val){
19 counter++;
20 binary_search(arr,key,left,mid-1);
21 }
22 else { // (key>=arr[mid].val)
23 binary_search(arr,key,mid+1,right);
24 }
25 }
26 int main() {
27 int arr[9]={1,2,3,5,5,5,6,7,9};
28 counter=0;
29 int j=binary_search(arr,5,0,8);
30 printf("%d",j);
31 printf("%d",counter);
32 }
第 41 題
What is the output of the code on Line 30?
(A) 2
(B) 3
(C) 4
(D) 5
(E) 6
登入後即可作答並保存紀錄。
核心觀念
binary_search 在已排序陣列中尋找 key 的插入位置。若 key 不小於整個區間的最右元素,回傳 right+1,也就是第一個大於 key 的位置(upper bound)。counter 記錄比較次數。
解題方法
以 binary_search(arr, 5, 0, 8) 逐步追蹤,arr 為 1, 2, 3, 5, 5, 5, 6, 7, 9:
(0, 8):5<arr[0]=1不成立;5>=arr[8]=9不成立;mid=4,arr[4]=5,5<5不成立,進入右半區間(5, 8)。(5, 8):5<arr[5]=5不成立;5>=arr[8]=9不成立;mid=6,arr[6]=6,5<6成立,counter加 1,進入左半區間(5, 5)。(5, 5):5<arr[5]=5不成立;5>=arr[5]=5成立,counter加 1,回傳right+1=6。
第 42 題
What is the output of the code on Line 31?
(A) 4
(B) 3
(C) 2
(D) 1
(E) larger than 4
登入後即可作答並保存紀錄。
核心觀念
這題考的是二分搜尋遞迴過程中的比較計數。全域變數 counter 只在四個位置遞增:Line 6(left>right)、Line 10(key<arr[left])、Line 14(key>=arr[right])、Line 19(key<arr[mid])。題目問的是 Line 31 印出的 counter 值,因此只要逐步追蹤條件是否成立即可,不需要處理遞迴回傳值。
解題方法
陣列為 arr = {1,2,3,5,5,5,6,7,9}(索引 0 到 8),呼叫 binary_search(arr, 5, 0, 8)。
- 第一次呼叫
(left=0, right=8):left>right不成立;key<arr[0]=1不成立;key>=arr[8]=9不成立。計算mid=(0+8)/2=4,arr[4]=5,key<arr[4]為 ,不成立,所以不計數,改走 else 遞迴(5, 8)。 - 第二次呼叫
(left=5, right=8):key<arr[5]=5不成立;key>=arr[8]=9不成立。計算mid=(5+8)/2=6,arr[6]=6,key<arr[6]成立,counter加 1(變為 1),遞迴(5, 5)。
第 43 題
The memmove function is declared in the <string.h> header file in C, and the <cstring> header file in C++. The function prototype is:
void *memmove(void *dest, const void *src, size_t count);
It copies count bytes from the src memory to the dest memory area, safely handling cases where the source and destination regions overlap. Its speed is generally excellent and optimized by compiler/hardware. The following code provides fast Insertion operation using both Binary Search and memmove. Which of the following statements is the least accurate?
void insert(int arr[], int n, int key) {
int j;
if (n<=0){
j=0;
}
else{
j=binary_search(arr,key,0,n-1);
}
if ((n-j)>0) {
memmove(arr+j+1,arr+j,(n-j)*sizeof(int));
}
arr[j]=key;
}
(A) It is stable.
(B) It is in-place.
(C) Computation complexity is O(n log n)
(D) Binary search has O(log n) computational complexity
(E) The insertion operation in an array using memmove can be as efficient as that of a linked list, provided there is optimized hardware support.
登入後即可作答並保存紀錄。
核心觀念
陣列插入的流程分兩步:先用二分搜尋找出插入位置 j,再用 memmove 把 arr[j..n-1] 整段右移一格,最後把 key 放入 arr[j]。判斷時要分開看三件事:穩定性(取決於二分搜尋的分支條件)、原地性(額外空間)、時間複雜度(比較與搬移的代價分開計算)。
解題方法
- 穩定性:二分搜尋的分支是
key<arr[mid]時往左,否則往右,因此j是「最後一個小於等於key的元素之後」的位置(upper bound)。相等元素的新值會插在舊值之後,原有相等元素的相對次序不變,插入是穩定的。 - 比較次數:二分搜尋只做比較、不搬移資料,比較次數為 。
- 搬移代價:
memmove要搬移 個 int,最壞情況j=0時要搬 個元素,因此單次插入的時間複雜度為 。 - 額外空間:插入只用到
j、key等固定數量的變數,額外空間為 。
選項分析
- (A) It is stable.:正確。插入位置為 upper bound,相等元素的相對次序不變。
- (B) It is in-place.:依台聯大公布的標準答案判定為本題最不精確的選項。依嚴格定義(只用 額外空間),這個插入操作確實是原地操作,這點與一般推論有出入。
第 44 題
Given the following pseudo code of Quicksort algorithm, which of the following statement is the least accurate?
Quicksort(A,p,r)
if p<r
q=Partition(A,p,r)
Quicksort(A,p,q-1)
Quicksort(A,q+1,r)
Partition(A,p,r)
x=A[r]
i=p-1
for j=p to r-1
if A[j]<=x
i=i+1
exchange A[i] with A[j]
exchange A[i+1] with A[r]
return i+1
(A) It is stable.
(B) It is in-place.
(C) Its worst time performance is O(n²).
(D) The output of Quicksort() is a non-decreasing sorted sequence.
(E) The variable x is usually called the pivot.
登入後即可作答並保存紀錄。
核心觀念
這段是使用 Lomuto 分割的快速排序:以 A[r] 為樞紐(pivot)x,把小於等於 x 的元素移到左側,再遞迴排序左右兩段。判斷選項時要看穩定性、原地性、最壞時間、輸出性質與術語。
解題方法
- 穩定性(反例):取 ,其中 、 是值相同的兩個元素,以下標區分。,兩個 2 都不小於等於 1,
i維持在 0;最後exchange A[1]與A[3],得到 。兩個 2 的相對次序從 在前變成 在前,因此不穩定。 - 原地性:分割只做元素交換,除了遞迴堆疊之外只用到固定數量的變數,額外空間為 。
- 最壞時間:若每次分割都得到長度 與 的兩段(例如已排序,或全部元素相同),則 ,得 。
- 輸出性質:分割後
A[q]位於最終位置,左側元素皆小於等於它,右側元素皆大於它,遞迴後整體為非遞減序列。 - 術語:x 是分割用的比較值,即樞紐(pivot)。
第 45 題
How many different insertion sequences of the key values using the hash function h(k) = k mod 10 and linear probing will result in the hash table shown below?
| slot | key |
|---|---|
| 0 | |
| 1 | |
| 2 | 42 |
| 3 | 23 |
| 4 | 34 |
| 5 | 52 |
| 6 | 46 |
| 7 | 33 |
| 8 | |
| 9 |
(A) 10
(B) 20
(C) 30
(D) 40
(E) 50
登入後即可作答並保存紀錄。
核心觀念
線性探測中,一個鍵若沒有落在它的雜湊位置 ,就表示插入時它的探測路徑 上的槽位都已被佔用。因此,每個被位移的鍵都必須排在「路徑上那些鍵」之後插入。把這些先後關係列出來,數出符合的插入順序即可。
解題方法
- 各鍵的雜湊位置:、、、、、。
- 各鍵的最終位置:42 在 2、23 在 3、34 在 4、52 在 5、46 在 6、33 在 7。
- 只有 52(路徑 2、3、4,最終在 5)與 33(路徑 3、4、5、6,最終在 7)被位移,其餘鍵都落在雜湊位置。
- 限制條件:
- 52 必須在 42、23、34 之後插入;
- 33 必須在 23、34、52、46 之後插入。
- 由於 42 先於 52,52 先於 33,所以 33 必為最後插入。
第 46 題
We have implemented a method to perform basic string compression using the counts of repeated characters. For example, the string "aaabbbbccccc" would be "a3b4c5". Which of the following strings will have the best compression ratio, which length(compressed_string)/length(original_string) is the smallest?
(A) 00011000011111011001101111011111
(B) aaaahhhhhhheeeeeeeeiiiiiiioooooo
(C) 99911111886666666666666666688888
(D) &&&&&&&&%%%%%%%%%$$$$###########
(E) Implementedamethodtoperformbasic
登入後即可作答並保存紀錄。
核心觀念
這題是行程長度壓縮(run-length encoding)。依題例,每一段連續相同的字元壓縮成「字元+次數」,壓縮後長度為每段 字元之和。原字串長度固定,因此壓縮比最小的字串,要具備「連續重複的段落長、段數少」的特徵。
解題方法
計算各選項的段數與壓縮後長度(以原字串長度為分母):
- (A):
000 11 0000 11111 0 11 00 11 0 1111 0 11111,共 12 段、每段次數都是個位數,壓縮後 24 個字元,比值 。 - (B):
a4 h7 e8 i7 o6,5 段,壓縮後 10 個字元,比值 。 - (C):
9×3 1×5 8×2 6×17 8×5,5 段,壓縮後為93 15 82 617 85,共 11 個字元,比值 。
第 47 題
In a doubly linked list, the number of pointers affected for an insertion will be?
(A) 5
(B) 4
(C) 0
(D) 1
(E) It depends on the insertion location.
登入後即可作答並保存紀錄。
核心觀念
雙向鏈結串列的每個節點有 prev 與 next 兩個指標。插入一個新節點時,需要設定的指標數量取決於新節點落在哪個位置。
解題方法
- 插入中間:新節點的
prev與next兩個指標要設定(2 個),前驅節點的next要指向新節點(1 個),後繼節點的prev要指向新節點(1 個),合計 4 個。 - 插入頭端:新節點的
next指向原頭節點、原頭節點的prev指向新節點,合計 2 個(若再計入頭指標本身則為 3 個)。 - 插入尾端:新節點的
prev指向原尾節點、原尾節點的next指向新節點,合計 2 個(若計入尾指標則為 3 個)。
第 48 題
What is the time complexity to reverse a string?
(A) O(n²)
(B) O(n)
(C) O(log n)
(D) O(1)
(E) O(n log n)
登入後即可作答並保存紀錄。
核心觀念
反轉字串要把每個字元移到它對應的位置,屬於線性時間問題。核心概念是「每個元素至少要被存取一次」,因此下界為 ;用首尾雙指標交換即可在 完成。
解題方法
用兩個指標分別指向字串的頭與尾,交換兩端字元後向中間移動,直到指標相遇。總共約進行 次交換,每次交換為常數時間,因此整體為 。若字串可修改,這個方法只需要 額外空間。
選項分析
第 49 題
Given an array of integers and a target value, return the indices of the two numbers that add up to the target. What type of data structures allows to deduce a brute-force O(n²) solution down to O(n) time complexity.
(A) Array
(B) linked list
(C) Heap
(D) Hashing
(E) Tree
登入後即可作答並保存紀錄。
核心觀念
兩數之和的暴力解要對每個元素再搜尋另一個元素,因此為 。若能在 時間內查詢「某個數值是否已出現、出現在哪個索引」,每個元素只需一次查詢,整體即為 。滿足這個需求的資料結構是雜湊表(hashing)。
解題方法
從左到右走訪陣列,對每個數字 計算 ,在雜湊表中查詢是否已見過;若有,直接回傳兩者索引;若無,把 與其索引存入雜湊表。每個元素只做一次查詢與一次插入,平均時間為 ,整體為 。
選項分析
第 50 題
The following pseudo code is a simple algorithm to generate a permutation of n items. Please fill in the BLANK area in Line 6 with a correct formula such that i <= j < n
1 function Uniform(m)
2 return a random integer between 0 and m-1;
3
4 function Permutation(A,n)
5 for i = 0 to n-2
6 j=i+Uniform(__________)
7 SWAP(A[i],A[j])
(A) n
(B) n-i
(C) i
(D) n-1
(E) n/2
登入後即可作答並保存紀錄。
核心觀念
這是 Fisher–Yates(Knuth shuffle)的變體:第 步在尚未定案的區間 中隨機選一個位置 ,與 交換。關鍵是讓 恰好落在 且機率均勻。
解題方法
Uniform(m) 回傳 的隨機整數,因此 落在 。要讓 對所有 都成立,需要 ,即 。取 時, 恰好涵蓋整個區間 ,每個位置機率相同。
檢查邊界: 時 ,; 時 ,。