def merge_sort(arr): if len(arr) == 1: return arr p = 0 n = len(arr) q = (p+n)//2 return merge(arr, merge_sort(arr[p:q]), merge_sort(arr[q:])) def merge(arr, arr1, arr2): temp = list() i = j = 0 for r in range(len(arr)): if i < len(arr1) and j < len(arr2): # <= 保證穩定性 if arr1[i] <= arr2[j]: temp.append(arr1[i]) i += 1 else: temp.append(arr2[j]) j += 1 else: if i < len(arr1): temp.extend(arr1[i:]) else: temp.extend(arr2[j:]) return temp
def quick_sort(arr): if len(arr) <= 1: return arr privot = arr[0] larr, rarr = partition(arr[1:], privot) return quick_sort(larr) + [privot] + quick_sort(rarr) def partition(arr, privot): i = 0 for j in range(len(arr)): if arr[j] < privot: arr[i], arr[j] = arr[j], arr[i] i += 1 j += 1 return arr[:i], arr[i:]
歸併排序能夠保證穩定的O(nlogn),但須要臨時空間進行合併,空間複雜度O(n)。算法
快速排序平均複雜度是O(nlogn),極端狀況下O(n^2),是不穩定的排序算法,不穩定的緣由和選擇排序相同(老是和「未排序」的第一個值交換),空間複雜度O(1),極端狀況出現的機率能夠控制的很低加上空間佔用低,因此快速排序應用普遍。app
兩種排序算法都使用了「分治」法,將大問題拆成多個小問題,因爲各個部分採用相同的邏輯進行排序,因此一般使用"遞歸"的方式進行處理。ui
快排不穩定舉例:5 3 2 5 1 假設privot=2,按照partition([5,3,5,1], 2)的結果是([1], [3, 5, 5]),顯然最後一個5是一開始最前面的那個5code