[Algorithm] Sorting 排序
Bubble Sort 泡沫排序 T: O(n ^ 2), S: O(1)
依序把最大的放到最後(如泡沫慢慢浮上水面)
- [2, 3, 5, 4, 1]
- [2, 3, 4, 1, 5]
- [2, 3, 1, 4, 5]
- [2, 1, 3, 4, 5]
- [1, 2, 3, 4, 5]
def bubble_sort (arr):
for i in range(len(arr)):
for j in range(len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
Insertion Sort 插入排序 T: O(n ^ 2), S: O(1)
- [2, 3, 5, 4, 1] ≡ 2 → [] = [2]
- [2, 3, 5, 4, 1]≡ 3 → [2] = [2, 3]
- [2, 3, 5, 4, 1]≡ 5 → [2, 3] = [2, 3, 5]
- [2, 3, 5, 4, 1]≡ 4 → [2, 3, 5] = [2, 3, 4, 5]
- [2, 3, 5, 5, 1]
- [2, 3, 4, 5, 1]
- [2, 3, 4, 5, 1]≡ 1 → [2, 3, 4, 5] = [1, 2, 3, 4, 5]
- [2, 3, 4, 5, 5]
- [2, 3, 4, 4, 5]
- [2, 3, 3, 4, 5]
- [2, 2, 3, 4, 5]
- [1, 2, 3, 4, 5]
def insertion_sort(arr):
for i in range(len(arr)):
key = arr[i]
j = i - 1
while j > 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
Shell Sort 希爾排序
選擇 Gap sequences 為 (5, 3, 1) 為例
- [13, 14, 94, 33, 82, 25, 59, 94, 65, 23, 45, 27, 73, 25, 39, 10]
- 5 – Sorting:
- [[13, 14, 94, 33, 82],
[25, 59, 94, 65, 23],
[45, 27, 73, 25, 39],
[10]] - 分別對每行進行插入排序
[[10, 14, 73, 25, 23],
[13, 27, 94, 33, 39],
[25, 59, 94, 65, 82],
[45]]
- [[13, 14, 94, 33, 82],
- 還原為一列:
[10, 14, 73, 25, 23, 13, 27, 94, 33, 39, 25, 59, 94, 65, 82, 45] - 3 – Sorting
- [[10, 14, 73],
[25, 23, 13],
[27, 94, 33],
[39, 25, 59],
[94, 65, 82],
[45]] - [[10, 14, 13],
[25, 23, 33],
[27, 25, 59],
[39, 65, 73],
[45, 94, 82],
[94]]
- [[10, 14, 73],
- 還原為一列:
[10, 14, 13, 25, 23, 33, 27, 25, 59 ,39, 65, 73, 45, 94, 82, 94] - 1 – Sorting(會比原始資料更容易做插入排序):
[10, 13, 14, 23, 25, 25, 27, 33, 39, 45, 59, 65, 73, 82, 94, 94]
Gap sequences 步長序列
| General term (k ≥ 1) | Concrete gaps | Worst-case Time Complexity |
| $$ \frac{n}{2^k} $$ | $$ \frac{n}{2}, \frac{n}{4}, …, 1 $$ | $$ \Theta(n^2) $$ |
| $$ 2^k – 1 $$ | $$ 1, 3, 7, 15, 31, 63, … $$ | $$ \Theta(n^\frac{3}{2}) $$ |
| $$ 2^p 3^q $$ (3-smooth number) |
$$ 1, 2, 3, 4, 6, 8, 9, 12, … $$ | $$ \Theta(n \log^2{n}) $$ |
Selection Sort 選擇排序 T: O(n ^ 2), S: O(n)
- [2, 3, 5, 4, 1] → [1, 3, 5, 4, 2]
- [1, 3, 5, 4, 2] → [1, 2, 5, 4, 3]
- [1, 2, 5, 4, 3] → [1, 2, 3, 4, 5]
- [1, 2, 3, 4, 5]
- [1, 2, 3, 4, 5]
def selection_sort(arr):
for i in range(len(arr) - 1):
min_i = i
for j in range(i + 1, range(len(arr)):
if arr[j] < arr[min_i]:
min_i = j
if min_i != i:
arr[i], arr[min_i] = arr[min_i], arr[i]
Quick Sort 快速排序 T: O(n * log(n)) ~ O(n ^ 2)
使用二分法 (binary method / divide and conquer)
- [5, 9, 6, 1, 3, 8, 4, 7, 2] → pivot: 5
→ less: [1, 3, 4, 2], greater: [9, 6, 8, 7]
→ quick_sort([1, 3, 4, 2]) + [5] + quick_sort([9, 6, 8, 7]) - → (
quick_sort([]) +[1] + quick_sort([3, 4, 2])) + [5] + (quick_sort([6, 8, 7]) + [9]+ quick_sort([])) - → ([1] + (quick_sort([2]) + [3] + quick_sort([4]))) + [5] + ((
quick_sort([]) +[6] + quick_sort([8, 7])) + [9]) - → ([1] + (([2]) + [3] + ([4]))) + [5] + (([6] + (
quick_sort([]) +[7] + quick_sort([8])) + [9]) - → ([1] + (([2]) + [3] + ([4]))) + [5] + (([6] + ([7] + [8])) + [9])
- → [1, 2, 3, 4, 5, 6, 7, 8, 9]
Time Complexity:
Average Case: O(n * log(n))
Worst Case: O(n ^ 2)
Space Complexity: Ω(n)
def quick_sort (arr):
if len(arr) <= 1: return array
pivot = arr[0] # select a pivot
less, greater = [], []
for n in arr[1:]:
if n <pivot:
less.append(n)
else:
greater.append(n)
return quick_sort(less) + [pivot] + quick_sort(greater)
In-plase Version, S: O(1)
- [5, 9, 6, 1, 4, 7, 3, 8, 2]
- [5, 9, 6, 1, 4, 7, 3, 8, 2]
- [5, 9, 6, 1, 4, 7, 3, 8, 2]
- [5, 1, 6, 9, 4, 7, 3, 8, 2]
- [5, 1, 4, 9, 6, 7, 3, 8, 2]
- [5, 1, 4, 9, 6, 7, 3, 8, 2]
- [5, 1, 4, 3, 6, 7, 9, 8, 2]
- [5, 1, 4, 3, 6, 7, 9, 8, 2]
- [5, 1, 4, 3, 2, 7, 9, 8, 6]
Time Complexity:
Average Case: O(n * log(n))
Worst Case: O(n ^ 2)
Space Complexity: O(1)
def quick_sort (arr):
if len(arr) <= 1: return array
pivot = arr[0] # select a pivot
greater_start = 1
for i, n in enumerate(array[1:]):
if n < pivot:
arr[i], arr[greater_start] = arr[greater_start], arr[i]
greater_start += 1
return quick_sort(arr[1:greater_start]) + [pivot] + quick_sort(arr[greater_start:])
Merge Sort 合併排序 T: Θ(n * log(n)), S: Θ(n)
| 2 | 3 | 5 | 4 | 1 | ||||
| ↙︎ | ↘︎ | |||||||
| 2 | 3 | 5 | 4 | 1 | ||||
| ↙︎ | ↘︎ | ↙︎ | ↘︎ | |||||
| 2 | 3 | 5 | 4 | 1 | ||||
| ↙︎ | ↘︎ | ↓ | ↓ | ↓ | ||||
| 2 | 3 | 5 | 4 | 1 | ||||
| ↘︎ | ↙︎ | ↓ | ↘︎ | ↙︎ | ||||
| 2 | 3 | 5 | 1 | 4 | ||||
| ↘︎ | ↙︎ | ↓ | ||||||
| 2 | 3 | 5 | 1 | 4 | ||||
| ↘︎ | ↙︎ | |||||||
| 1 | 2 | 3 | 4 | 5 |
def merge_sort(array):
if len(array) < 2: return array
mid = (len(array) + 1) // 2
left = merge_sort(array[:mid])
right = merge_sort(array[mid:])
ret = []
i = j = 0
while i < len(left) or j < len(right):
if i == len(left) or \
(i < len(left) and j < len(right) and left[i] > right[j]):
ret.append(right[j])
j += 1
else:
ret.append(left[i])
i += 1
return ret
相關例題
Heap Sort
參照 Heap 堆積
Last Updated on 2024/06/10 by A1go