排序算法之歸併排序及其優化

歸併排序


其餘排序方法:選擇排序冒泡排序歸併排序快速排序插入排序希爾排序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

其餘排序方法:選擇排序冒泡排序歸併排序快速排序插入排序希爾排序性能

相關文章
相關標籤/搜索