演算法
CH1 Union-Find 演算法
演算法的方法
- Find -> 看 p 這個點在哪裡
- Connected -> 看 p q 兩點是否相連
- Union -> 把 p q 兩點連在一起
quick-find
id[] 裡面存的是,如果數字一樣 -> 同 union
- Find -> 看 p 的 id 是多少
- Connected -> 看 p q 兩點的 id 是否一樣
- Union -> 把 id[p] 的值放到 id[q] 裡
algorithm |
initialize |
union |
find |
connected |
quick-find |
N |
N |
1 |
1 |
quick-union
用 tree 的想法實作
id[] 裡面存的是,這個點的 root(最上面的點) 是誰
- Find -> p 點的 root 是誰
- Connected -> 看 p q 的 root 是否一樣
- Union -> 把 p 的 root 指向 q 的 root
algorithm |
initialize |
union |
find |
connected |
quick-find |
N |
N |
1 |
1 |
quick-union(worst case) |
N |
N |
N |
N |
- 最好的情況
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- 最壞的情況
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
weighted QU
- 在 union 的過程中有可以小樹接在大樹上
- 會把 tree height 變高
- 改量方法為永遠是 大樹接小樹
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
algorithm |
initialize |
union |
find |
connected |
quick-find |
N |
N |
1 |
1 |
quick-union(worst case) |
N |
N |
N |
N |
weighted QU (worst case) |
N |
lg N |
lg N |
lg N |
- 為什麼是 lg N 呢
- 因為每次 union 後的 size 都會至少是小數的 2 倍大
- 以 1, 2, 4, 8, 16, …成長
- 所以 union 的次數一定會小於 lg N
CH2 演算法分析
CH3 未知矩陣大小問題
Link-list
- 在最糟的情況下,執行時間為 constant
- 需要花很多空間來存 link
Resizing Arrays
- 每次執行,執行時間為 constant
- 不需要花太多空間
-
一次增加矩陣一格
-
一次增加原本矩陣的一半
-
一次減少四分之一
CH4 sort
Selection sort 選擇排序法
-
流程
- 從 未排序 的數列中找到最小的元素
- 將此元素取出並加入到 已排序 數列最後
- 重複以上動作直到未排序數列全部處理完成

Insertion sort 插入排序法
-
流程
- 從 未排序 數列取出一元素
- 由後往前和 已排序 數列比較
- 遇到 不大於自己 的元素並插入此元素之後
- 若都沒有則插入在最前面。
- 重複以上動作直到未排序數列全部處理完成。

- 所花時間
- 最好情況
- 如果數列已經是排好的
- ex:"1, 2, 3, 4, 5, 6"
- compares:
- exchange:
- 最壞情況
- 如果數列剛好是反過來排好的
- ex:"6, 5, 4, 3, 2, 1"
- compares:
- exchange:
- 平均情況
Shellsort
- 流程
- 將整個陣列依照預先指定的間隔長度 d
- 交錯分割成數個小陣列
- 以插入排序的方式將這些小陣列個別排序
- 逐漸縮小間隔長度 d ,直到 d 等於 1
- 一般用 3x + 1 的方法

CH5 Merge sort 合併排序法
Top-Down Merge sort
- 使用 divide and conquer 分而治之的方法
- 使用遞迴的方法
-
流程
- 將陣列分割直到只有一個元素 -> 遞迴
- 開始兩兩合併,每次合併同時進行排序,合併出排序過的陣列
- 重複2的動作直接全部合併完成

merge 方法
sort 方法
- 所花時間
- compares:
- proof:
左半邊 + 右半邊 + merge
- 樹高為 lg N


Buttion-Up Merge sort
sort 方法

Timsort
- 結合了 merge sort 和插入排序 insertion sort 而得出的排序算法
- 為了優化在排序時有時已經排好的問題
- 以一個區塊進行排序
- 流程
- 找到各區塊 以一個排好的數列為一區塊
- 以 merge sort 合併各個 區塊

stability 穩定性
- 如果在一個待排序的序列中,存在2個相等的數
- 在排序後這2個數的相對位置保持不變
- 那麼該排序演算法是穩定的
- 否則是不穩定的
ex:(A, A*, C, D, E)(20, 20, 10, 50, 30)
stability (C, A, A*, E, D)
unstability (C, A*, A, E, D)
- 另一種看法
- 看有沒有長距離搬移
- 有的話就有可能是 unstability
Sleep sort
- 根據 thread 的 sleep
- 數字越小 睡得越早,越早起來
CH6 Quick sort 快速排序法
quick sort
- 排序演算法的一種
- 使用Divide and Conquer的演算法來實作
- 可以使用 in-place 來實作,但不合成本
-
流程
- 數列中選擇一元素作為基準點(pivot)
- 小於此元素的移至基準的左邊,大於此元素的移至右邊,相等的任意放
- 基準點左邊和右邊視為兩個數列,並重複做以上動作直到數列剩下一個或零個元素。
-
所花時間
-
最好情況
- 當選中的 pivot 都是當下的中位數時
- compares:
-
最壞情況
- 當數列已經是排好的了
- compares:
- proof:

-
平均情況
表示本次 pivot 所需比較次數
與每種分割結果所需比較次數的期望和
通乘以 n 得
式1
把 n 換成 n - 1 得
式2
把 式1 - 式2 得
移位後,同除以 得
用積分化減得
3 ways quick sort
- 用來解決 quick sort 遇到一樣的數字時,會再 compare 一次
- 原本 quick sort 只會分成兩等分:大於 pivot 或小於 pivot
- 3 ways 則分成三等分:大於 pivot、等於 pivot、小於 pivot
-
流程
- (a[i] < v):交換 a[lt] 和 a[i]、增加 lt 和 i
- (a[i] > v):交換 a[gt] 和 a[i]、減少 gt
- (a[i] == v):增加 i

總整理
|
inplace |
stable |
最好情況 |
平均情況 |
最壞情況 |
優點 |
selection |
✔ |
|
|
|
|
只交換 N 次 |
insertion |
✔ |
✔ |
N |
|
|
如果 N 特別小的話 效率高,會接近 constant |
shell |
✔ |
|
|
? |
? |
|
merge |
|
✔ |
|
|
|
穩定保證 |
timsort |
|
✔ |
N |
|
|
改良 mergesort 優化已經排序的數列 |
quick |
✔ |
|
|
|
|
最快的排序法 |
3-way quick |
✔ |
|
N |
|
|
優化 quicksort 遇到相同數字的問題 |
heap |
✔ |
|
N |
|
|
保證 |
Heap Sort