Main Idea: use two loops to iterate data array, find the maximum, and throw it to the end.
(兩次循環,每次選大的放在後面,重複,直到沒有數據)python
Feature: Stable
O(n^2)git
def bubble_sort(arr): for i in range(len(arr)): for j in range(0, len(arr) - i - 1): if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] return arr
Alternative: add a flag into outter loop, reducing the # of comparison.
(經過在外循環設置標誌位,能夠減小比較的次數,但意義不大)github
def bubble_sort(arr): for i in range(len(arr)): flag = 0 for j in range(0, len(arr) - i - 1): if arr[j] >= arr[j + 1]: flag += 1 arr[j], arr[j + 1] = arr[j + 1], arr[j] if flag == 0: break return arr
Test Code Linkredis
Main Idea: use two loops to iterate data array, find the minimum, and insert it at the beginning.
(兩次循環,每次選小的放在前面,重複,直到沒有數據)app
Feature: Unstable
O(n^2)less
def selection_sort(arr): for i in range(len(arr)): for j in range(i, len(arr)): if arr[i] > arr[j]: arr[i], arr[j] = arr[j], arr[i] return arr
Alternative: store the current index, reducing the # of switching.
(經過在外循環存儲的索引, 減小數據交換的次數)ide
def selection_sort(arr): for i in range(len(arr)): min_idx = i for j in range(i, len(arr)): if arr[min_idx] > arr[j]: min_idx = j if i != min_idx: arr[i], arr[min_idx] = arr[min_idx], arr[i] return arr
Main Idea: use two loops to iterate data array simultaneously, insert a new data item into sorted results at an appropriate location. and push the rest data behind this location as a whole.
(兩次循環,將無序數據插入到已經有序的結果中,在插入位置,將後面的數據總體後移,重複,直到沒有數據)oop
Feature: Stable
O(n^2)ui
def insertion_sort(arr): for i in range(len(arr)): prev_idx = i - 1 current = arr[i] while prev_idx >= 0 and arr[prev_idx] > current: arr[prev_idx + 1] = arr[prev_idx] prev_idx -= 1 arr[prev_idx + 1] = current return arr
Alternative1: use binary search to find the location where the new element should insert.
(用二分查找,找到須要插入的位置)
def insertion_sort(arr): for i in range(len(arr)): current = arr[i] low, high = 0, i - 1 while low <= high: mid = int((low + high) / 2) if current < arr[mid]: high = mid - 1 else: low = mid + 1 for j in range(i, low, -1): arr[j] = arr[j - 1] arr[low] = current return arr
Alternative2: use a descreasing number as a gap, to accelerate seaching process.
(用一個遞減的數值,做爲間隔,每輪中,比較每一個間隔對應的值,結合直接插入排序。 還有另一個名字-希爾排序)
def insertion_sort(arr): gap = len(arr) // 2 while gap >= 1: for i in range(gap, len(arr)): end_val = arr[i] front_idx = i - gap while front_idx >= 0 and arr[front_idx] > end_val: arr[front_idx + gap] = arr[front_idx] front_idx -= gap arr[front_idx + gap] = end_val gap //= 2 return arr
Feature: Unstable
O(nlogn)
Main Idea: a classic sorting solution using divide-and-conquer. split data into pieces, and sort those small data and combine all of them.
(遞歸地把當前序列平均分紅兩半, 分到只剩一個元素的時候, 中止切分開始進行兩兩排序,當解決完N個小問題以後,就能夠把結果再拼裝起來)
Feature: Stable
O(nlogn)
def merge(left, right): res = [] while left and right: min_val = left.pop(0) if left[0] < right[0] else right.pop(0) res.append(min_val) res += left if left else right return res def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right)
Alternative: instead, use a recursion method to write this algorithm, we can also use an iteration way.
(除了使用遞歸方式去實現歸併排序,也能夠使用迭代的思路去實現)
def merge(arr, low, mid, high): left = arr[low: mid] right = arr[mid: high] res = [] while left and right: min_val = left.pop(0) if left[0] < right[0] else right.pop(0) res.append(min_val) res += left if left else right arr[low: high] = res def merge_sort(arr): sub_length = 1 while sub_length < len(arr): low = 0 while low < len(arr): mid = low + sub_length high = min(low + 2 * sub_length, len(arr)) if mid < high: merge(arr, low, mid, high) low += 2 * sub_length sub_length *= 2 return arr
Test Code Link1 | Test Code Link2
Main Idea: another classic solution using divide-and-conquer. choose an item as pivot, split data into two part, one part is less than pivot, the rest will greater than pivot. continue doing this until no data.
(經過設置樞軸的方式,將原始數據分紅兩個部分,將兩個小部分排序並把結果最後合起來,重複切分,直到沒有數據)
Feature: Unstable
O(nlogn)
def quick_sort(arr, left, right): if left < right: pivot = arr[right] low, high = left, right while left< right: while left < right and arr[left] < pivot: left += 1 arr[right] = arr[left] while left < right and arr[right] > pivot: right -= 1 arr[left] = arr[right] arr[left] = pivot quick_sort(arr, low, left - 1) quick_sort(arr, left + 1, high) return arr
Alternative1: the most easy way to do quick sorting.
(我認爲是最容易理解的一種實現方式)
def quick_sort(arr): if arr: pivot = arr[0] less = [x for x in arr if x < pivot] great = [x for x in arr if x > pivot] return quick_sort(less) + [pivot] + quick_sort(great) else: return []
Alternative2: 1. return the index of pivot. 2. split the data.
(設置一個函數返回樞軸的位置,以此位置切分原始數據,一直迭代下去)
def quick_sort(arr, left, right): if left < right: pivot_idx = split(arr, left, right) quick_sort(arr, left, pivot_idx - 1) quick_sort(arr, pivot_idx + 1, right) return arr def split(arr, left, right): pivot = arr[right] i = left - 1 for j in range(left, right): if arr[j] <= pivot: i += 1 arr[i], arr[j] = arr[j], arr[i] arr[i + 1], arr[right] = pivot, arr[i + 1] return i + 1
Test Code Link1 | Test Code Link2
Main Idea: convert data item into key-value pair, the iterate the keys.
(將輸入的數據值轉化爲鍵存儲在額外開闢的桶空間中,而後遍歷生成的桶,從小到大依次拿出來就是結果)
Feature: Stable
O(n + k)
def bucket_sort(arr): buckets = [0] * ((max(arr) - min(arr)) + 1) for i in range(len(arr)): buckets[arr[i] - min(arr)] += 1 res = [] for i in range(len(buckets)): if buckets[i] != 0: res += [i + min(arr)] * buckets[i] return res
Waning: to be honest, no one will use this to solve real-world problem. will waste lot of memory space.
(沒什麼人會用)
Main Idea: distribute the data into buckets based on their unit digit. and collect all of them, and then redistribute them based on their tens digit, continue doing this way.
(依次用原始數據各項的個十百等數位進行映射,每次映射後,再將桶裏的數據依次提出來,覆蓋表原來的數據,重複下去直到全部數位都用完)
Feature: Stable
O(n*k)
def radix_sort(arr): digit = 0 max_digit = 1 max_value = max(arr) while 10 ** max_digit < max_value: max_digit += 1 while digit < max_digit: buckets = [[] for _ in range(10)] for i in arr: num = int((i / 10 ** digit) % 10) buckets[num].append(i) temp_result = [] for bucket in buckets: temp_result.extend(bucket) arr = temp_result digit += 1 return arr
Warning: What should I say, same as the counting sort, even though it has some improvement.
(跟計數排序同樣,沒人用)
筆記完整代碼Github: https://github.com/AaronYang2333/CSCI_570/wiki 持續更新!