這題佔了整整 20 分,分為 (a) 排序演算法追蹤 以及 (b) Big-O 時間複雜度計算 兩個部分。以下為詳細的批改與費曼解析!
O(n),看到乘除倍數逼近的通常是 O(log n)。目標:將數列 33, 30, 57, 41, 74, 18, 52, 60 以遞增順序排序。
✅ 你的答案:完美!(3/3 marks)
初始: 33, 30, 57, 41, 74, 18, 52, 60
Pass 1: [30 33] 57 41 74 18 52 60
Pass 2: [30 33 57] 41 74 18 52 60
Pass 3: [30 33 41 57] 74 18 52 60
Pass 4: [30 33 41 57 74] 18 52 60
Pass 5: [18 30 33 41 57 74] 52 60
Pass 6: [18 30 33 41 52 57 74] 60
Pass 7: [18 30 33 41 52 57 60 74]
教授點評:你完美地展現了「撲克牌插入」的邏輯,每一次 Pass 都精準地把下一個數字放進左邊已排好序的陣列中!
✅ 你的答案:n^2 (1/1 mark)
教授點評:觀念完全正確!但在正式考卷上,請務必記得加上 Big-O 的括號,寫成 O(n²) 才能穩穩拿分喔!
✅ 你的答案:精準!(4/4 marks)
[33 30 57 41] [74 18 52 60]
[33 30][57 41][74 18][52 60]
[30 33][41 57][18 74][52 60]
[30 33 41 57][18 52 60 74]
[18 30 33 41 52 57 60 74]
教授點評:你把 Divide and Conquer 的精神發揮得淋漓盡致。從 8個切成 4-4、2-2,再完美地合併,這 4 分拿得實至名歸。
⚠️ 批改:掉進指標陷阱了 (0/5 marks)
你的答案從 Step 3 開始亂掉了,把 storeIndex 的用途搞混了。storeIndex 就像是一個「小於 33 的專屬座位區邊界」。我們來一步步走:
初始: 33, 30, 57, 41, 74, 18, 52, 60 (Pivot=33, storeIndex=1)
Step 1 (val=30): 30 < 33 ➔ 丟進 storeIndex(1),自己跟自己交換沒變化。storeIndex 變成 2。
[ 33, 30, 57, 41, 74, 18, 52, 60 ] | storeIndex = 2
Step 2 (val=57): 57 > 33 ➔ 不理它,storeIndex 停在 2。
Step 3 (val=41): 41 > 33 ➔ 不理它,storeIndex 停在 2。
Step 4 (val=74): 74 > 33 ➔ 不理它,storeIndex 停在 2。
Step 5 (val=18): 18 < 33 ➔ 抓到了!跟 storeIndex(2) 的位子(57)交換!
[ 33, 30, 18, 41, 74, 57, 52, 60 ] | storeIndex 變成 3
Step 6 (val=52): 52 > 33 ➔ 不理它。
Step 7 (val=60): 60 > 33 ➔ 不理它。
Step 8 (Swap Pivot): 把 Pivot(33) 跟 storeIndex - 1 (Index 2 的 18) 交換!
✅ 最終正確答案:[ 18, 30, 33, 41, 74, 57, 52, 60 ]
⚠️ 你的答案:中間的數字愈小 (0/2 marks)
👨🏫 教授的理論解析:這題考的是「資料的初始狀態」對效能的影響。如果資料「已經排好序了」,你總是選「第一個數字」當 pivot,切出來的兩半會是 0 個與 n-1 個,會讓 Quick Sort 退化成 O(n²) 的最壞情況!
選「中間的數字」當 pivot,能把它完美切成一半一半,效能維持在最佳的 O(n log n)。
考驗判斷程式碼執行效率的眼力!抓到迴圈變數 (loop variable) 的變化規律就能秒殺。
int sum = 0;
for (int i=n+1000; i>=1; i-=10)
sum += i;
⚠️ 你的答案:n/2 (0/1 mark)
✅ 正確答案:O(n)
👨🏫 教授點評:你觀察到它執行了約 (n+1000)/10 次。但在 Big-O 的世界裡,黃金法則必背:「忽略所有常數 (Drop the constants)」!只要迴圈是以固定的步距做加減,它就是線性的 O(n)。
int sum = 0;
for (int i=1; i<=n; i*=3)
sum += i;
⚠️ 你的答案:nlogn (0/2 marks)
✅ 正確答案:O(log n)
👨🏫 教授點評:觀察 i*=3!它的成長軌跡是 1, 3, 9, 27, 81... 呈指數級暴增!只要是用「乘法 (*) 或除法 (/) 以倍數朝邊界逼近」,時間複雜度就是對數級別 O(log n)。
int sum = 0;
for (int i=1; i<=n/2; i++)
for (int j=n; j>1; j/=3)
sum += (i*j);
⚠️ 你的答案:n^2logn (0/2 marks)
✅ 正確答案:O(n log n)
👨🏫 教授點評:巢狀迴圈要把外層與內層「相乘」。外層是 i++ 到 n/2,複雜度為 O(n);內層是 j/=3 到 1,複雜度為 O(log n)。兩者相乘即為 O(n log n)。你多給了一個平方,要小心不要混淆了!