其餘排序方法:選擇排序、冒泡排序、歸併排序、快速排序、插入排序、希爾排序html
歸併排序,顧名思義,兩個有序的數組合併成一個有序的數組。只要數組的長度大於1,均可以先分爲兩個數組,並將這兩個子數組排好序再合併。python
歸併排序時穩定的排序算法,平均時間複雜度和最好最壞時間複雜度均爲O(nlogn)。算法
Python代碼:數組
# 歸併排序 # left爲歸併區域的第一個下標,right爲歸併區域的最後一個下標 def mergeSort(arr, left, right): if left >= right: return # 中間下標 mid = left + right >> 1 # 歸併當前區域的左半邊區域 mergeSort(arr, left, mid) # 歸併當前區域的右半邊區域 mergeSort(arr, mid + 1, right) # 合併左右兩邊區域並排序 merge(arr, left, mid, right) # 合併左右兩邊區域並排序 # left爲左邊區域的第一個下標,mid爲左邊區域的最後一個下標 # mid+1爲右邊區域的第一個下標,right爲右邊區域的最後一個下標 def merge(arr, left, mid, right): # 排序須要藉助一個數組 tmpArr = [] i, j = left, mid + 1 # 同時循環左右兩個區域,小的數先移進tmpArr,直到其中一個區域沒有數據 while i <= mid and j <= right: if arr[i] <= arr[j]: tmpArr.append(arr[i]) i += 1 else: tmpArr.append(arr[j]) j += 1 # 若左邊區域還有數據,則直接添加到後面 while (i <= mid): tmpArr.append(arr[i]) i += 1 # 若右邊區域還有數據,則直接添加到後面 while (j <= right): tmpArr.append(arr[j]) j += 1 # 將合併排好序的數據複製到原數組 for x in tmpArr: arr[left] = x left += 1
咱們會發現若是左右數組的數據恰好有序,那上述代碼中,仍會將數據先複製到tmpArr,再複製回原數組。
只要在merge方法前加上下面的判斷,就能使最好時間複雜度降爲O(n):app
# 右邊區域的值所有比左邊區域的值大時,則不須要進行合併排序 if arr[mid] <= arr[mid + 1]: return arr
# 歸併排序 # left爲歸併區域的第一個下標,right爲歸併區域的最後一個下標 def mergeSort(arr, left, right): if left >= right: return # 中間下標 mid = left + right >> 1 # 歸併當前區域的左半邊區域 mergeSort(arr, left, mid) # 歸併當前區域的右半邊區域 mergeSort(arr, mid + 1, right) # 合併左右兩邊區域並排序 merge(arr, left, mid, right) # 合併左右兩邊區域並排序 # left爲左邊區域的第一個下標,mid爲左邊區域的最後一個下標 # mid+1爲右邊區域的第一個下標,right爲右邊區域的最後一個下標 def merge(arr, left, mid, right): # 右邊區域的值所有比左邊區域的值大時,則不須要進行合併排序 if arr[mid] <= arr[mid + 1]: return arr # 排序須要藉助一個數組 tmpArr = [] i, j = left, mid + 1 # 同時循環左右兩個區域,小的數先移進tmpArr,直到其中一個區域沒有數據 while i <= mid and j <= right: if arr[i] <= arr[j]: tmpArr.append(arr[i]) i += 1 else: tmpArr.append(arr[j]) j += 1 # 若左邊區域還有數據,則直接添加到後面 while (i <= mid): tmpArr.append(arr[i]) i += 1 # 若右邊區域還有數據,則直接添加到後面 while (j <= right): tmpArr.append(arr[j]) j += 1 # 將合併排好序的數據複製到原數組 for x in tmpArr: arr[left] = x left += 1