歡迎來到演算法的世界!

你好!今天,我們要深入探討電腦科學中最令人興奮的部分之一:演算法 (Algorithms)。別被這個名詞嚇倒了——演算法其實只是一套為了解決問題而設計的步驟指令。無論是跟隨食譜烘焙蛋糕,還是給朋友指引你家的路線,你其實都在使用演算法!

在本節中,我們將學習如何設計這些指令,了解每位程式設計師都必須知道的「經典」演算法,並看看如何透過堆疊 (Stacks)佇列 (Queues) 來管理數據。讓我們開始吧!


1. 理解演算法設計

在編寫程式碼之前,我們需要先進行規劃。當我們為某種情況分析 (analyze)設計 (design) 演算法時,需要考慮三個重點:

1. 輸入 (Inputs):開始時我們有什麼數據?
2. 處理 (Processes):我們需要什麼步驟來處理這些數據?
3. 輸出 (Outputs):最終結果應該是什麼樣子?

例子: 如果你要設計一個演算法來判斷學生考試是否及格,輸入就是分數,處理就是將分數與 50 分進行比較,而輸出就是「及格」或「不及格」。

快速回顧:優質演算法的目標

一個好的演算法應該是清晰的(沒有令人困惑的步驟)、高效的(不會花費不必要的時間),並且是準確的(總是能得出正確答案)。


2. 搜尋演算法

想像你在撲克牌堆中尋找特定的一張牌。你會怎麼找?在電腦科學中,我們使用兩種主要的「標準」演算法來在列表中尋找數據。

線性搜尋 (Linear Search)

這是最基礎的搜尋方法。你從列表的開端開始,逐一檢查每一項,直到找到目標為止。

步驟:
1. 查看第一個項目。
2. 是你要找的嗎?如果是,停止!
3. 如果不是,移動到下一個項目。
4. 重複上述過程,直到找到項目或到達列表末端。

現實類比: 在亂糟糟的衣堆中尋找某件特定的襯衫。你必須拿起每一件襯衫檢查,直到找到正確的那一件。

二分搜尋 (Binary Search)

這是一種速度快得多的「分治法 (divide and conquer)」,但有一個前提:列表必須是已排序的(例如按字母或數字順序),你才能開始。

步驟:
1. 找出列表的中間項目。
2. 你要找的項目等於中間值嗎?如果是,停止!
3. 你要找的項目小於中間值嗎?如果是,捨棄列表的右半部。
4. 如果大於中間值?捨棄列表的左半部。
5. 對剩餘的部分重複上述過程,直到找到為止。

現實類比: 在字典中尋找一個單字。你不會從第 1 頁開始找,而是從中間翻開,然後決定是要往前還是往後翻。

快速比較:
- 線性搜尋: 適用於任何列表(未排序或已排序),但在數據量大時很慢。
- 二分搜尋: 對於大型列表速度極快,但只在列表已排序的情況下有效。

關鍵點: 對於小型或未排序的列表使用線性搜尋。對於大型且已排序的列表使用二分搜尋。


3. 排序演算法

電腦通常需要將數據按順序排列。我們專注於兩種主要方法:泡沫排序 (Bubble Sort)插入排序 (Insertion Sort)

泡沫排序 (Bubble Sort)

在泡沫排序中,透過比較相鄰數字,最大的項目會像氣泡一樣「浮」到列表的末端。

步驟:
1. 查看前兩個項目。
2. 如果順序不對,將它們互換 (swap)
3. 移動到下一對(第 2 和第 3 個)並重複,直到到達末端。
4. 這是一次「掃描 (pass)」。重複整個過程,直到完成一次掃描且沒有任何互換發生。

你知道嗎? 泡沫排序通常被認為最容易理解,但對於大型列表來說也是最慢的演算法之一!

插入排序 (Insertion Sort)

這個演算法透過一次處理一個項目來建立一個已排序的列表。

步驟:
1. 從第二個項目開始。
2. 將它與前面的項目進行比較。
3. 將它插入 (insert) 到正確的位置。
4. 移動到第三個項目並重複,直到整個列表排序完成。

現實類比: 整理手中的撲克牌。你一次拿起一張牌,然後將它滑入你已經拿在手中的牌的正確位置。

記憶小撇步:如何分辨?

- 泡沫 (Bubble): 交換相鄰項目(就像氣泡上升)。
- 插入 (Insertion): 選取一個項目並將其「插入」到已排序的子列表中。

關鍵點: 泡沫排序簡單但需要很多交換。插入排序通常較快,特別是如果列表已經是「部分」排序的。


4. 資料結構:堆疊與佇列

演算法不僅用於搜尋和排序,還可以幫助我們對堆疊 (Stacks)佇列 (Queues) 等結構進行數據的添加 (add)移除 (remove)

堆疊 (Stack) - LIFO

堆疊遵循 LIFO 原則:後進先出 (Last-In, First-Out)

關鍵操作:
- 推入 (Push): 將項目添加到堆疊的頂端
- 彈出 (Pop): 從堆疊的頂端移除項目。

現實類比: 自助餐廳的托盤堆。你將新托盤放到頂端,而當有人需要時,他們也從頂端拿走一個。如果不拿走上面所有的托盤,你就無法拿到最底下的那個!

佇列 (Queue) - FIFO

佇列遵循 FIFO 原則:先進先出 (First-In, First-Out)

關鍵操作:
- 進入佇列 (Enqueue): 將項目添加到隊伍的末端
- 離開佇列 (Dequeue): 從隊伍的前端移除項目。

現實類比: 在商店排隊。第一個排進隊伍的人是第一個獲得服務的人,這才公平!

避免常見錯誤: 別搞混你的指標!在堆疊中,我們只關心頂端 (Top)。在佇列中,我們需要同時追蹤前端 (Front)末端 (Back)

關鍵點: 堆疊就像垂直堆疊(LIFO)。佇列就像水平隊伍(FIFO)。


5. 給你的最後建議

如果這些演算法起初看起來很棘手,別擔心。學習它們的最好方法是在紙上追蹤 (trace) 它們的過程。畫出一串數字,例如 \( [5, 2, 9, 1] \),然後親自嘗試一步步執行「泡沫排序」!

快速總結表

線性搜尋: 適用任何列表,速度慢。
二分搜尋: 僅限已排序列表,速度快。
泡沫排序: 交換相鄰項,簡單但慢。
插入排序: 插入已排序部分,適合小型列表。
堆疊: 後進先出 (LIFO)。
佇列: 先進先出 (FIFO)。

祝你複習順利!你一定能做到的!