九大排序演算法的手寫實現及時空複雜度分析
一、氣泡排序
氣泡排序是一種簡單的排序方法,演算法如下:
1. 首先將所有待排序的數字放入工作列表中。
2. 從列表的第一個數字到倒數第二個數字,逐個檢查:若某一位上的數字大於他的下一位,則將它與它的下一位交換。
3. 重複2號步驟(倒數的數字加1。例如:第一次到倒數第二個數字,第二次到倒數第三個數字,依此類推…),直至再也不能交換。
程式碼實現如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
最差時間複雜度 O(n²)
最優時間複雜度 O(n)
平均時間複雜度 O(n²)
最差空間複雜度 O(n) total, O(1) auxiliary
二、插入排序
插入排序也是一種簡單排序方法,演算法如下:
1. 從第一個元素開始,認為該元素已經是排好序的。
2. 取下一個元素,在已經排好序的元素序列中從後向前掃描。
3. 如果已經排好序的序列中元素大於新元素,則將該元素往右移動一個位置。
4. 重複步驟3,直到已排好序的元素小於或等於新元素。
5. 在當前位置插入新元素。
6. 重複步驟2。
程式碼實現如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
最差時間複雜度 O(n²)
最優時間複雜度 O(n)
平均時間複雜度 O(n²)
最差空間複雜度 O(n) total, O(1) auxiliary
三、選擇排序
選擇排序的思想如下:
1. 設陣列記憶體放了n個待排數字,陣列下標從1開始,到n結束。
2. i=1
3. 從陣列的第i個元素開始到第n個元素,尋找最小的元素。(具體過程為:先設arr[i]為最小,逐一比較,若遇到比之小的則交換)
4. 將上一步找到的最小元素和第i位元素交換。
5. 如果i=n-1演算法結束,否則回到第3步
程式碼實現如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
最差時間複雜度 О(n²)
最優時間複雜度 О(n²)
平均時間複雜度 О(n²)
最差空間複雜度 О(n) total, O(1) auxiliary
以上三種排序的時間複雜度都是O(n²)。
四、快速排序
實踐證明,快速排序是所有排序演算法中最高效的一種。它採用了分治的思想:先保證列表的前半部分都小於後半部分,然後分別對前半部分和後半部分排序,這樣整個列表就有序了。
快速排序的基本演算法是:
1. 從數列中挑出一個元素,稱為 “基準”(pivot),也叫作支點,
2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割之後,該基準是它的最後位置。這個稱為分割(partition)操作。
3. 遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個演算法總會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。
程式碼實現如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28