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),極端情況出現的概率可以控制的很低加上空間占用低,所以快速排序應用廣泛。
兩種排序算法都使用了“分治”法,將大問題拆成多個小問題,由於各個部分采用相同的邏輯進行排序,所以通常使用"遞歸"的方式進行處理。
快排不穩定舉例:5 3 2 5 1 假設privot=2,按照partition([5,3,5,1], 2)的結果是([1], [3, 5, 5]),顯然最后一個5是一開始最前面的那個5