1. 程式人生 > >歸併排序詳解和動畫

歸併排序詳解和動畫

歸併排序演算法思想:將陣列不斷二分得到子陣列,知道子陣列長度為1(自然是排序好的),對左子陣列和右子陣列分別排序,

子陣列長度為1,2,4....,

子陣列排序使用了一個輔助陣列

def exchange(arr,i,j):
    temp=arr[i]
    arr[i]=arr[j]
    arr[j]=temp

#歸併需要一個額外陣列存放歸併前的子陣列排序狀態
def merge(arr,start,mid,end):
    i=start
    j=mid+1
    aux[start:end+1]=arr[start:end+1]
    for idx in range(start,end+1):
        if i>mid:
            arr[idx] = aux[j]
            j += 1
        elif j > end:
            arr[idx] = aux[i]
            i += 1
        elif aux[j] < aux[i]:
            arr[idx] = aux[j]
            j += 1
        else:
            arr[idx] = aux[i]
            i += 1
        record.append(arr.copy())#動畫程式碼

對於i,j下標指標的邊界條件判斷和他們對應的陣列值的比較是這段程式碼的關鍵!

下面是遞迴二分(自頂向下然後再回溯)的過程

def sortUB(arr,start,end):
    if start>=end:
        return
    mid=start+(end-start)//2
    sortUB(arr,start,mid)
    sortUB(arr,mid+1,end)
    merge(arr,start,mid,end)

時間複雜度:O(nlogn)

空間複雜度:O(n)

下面看一個非常tricky的自底向上的歸併排序:

def sortBU(arr,start,end):
    n = len(arr)
    size = 1
    while size < n:
        idx = 0
        while idx < n - size:
            merge(arr,idx,idx + size - 1,idx + 2 * size - 1)
            idx += 2*size
        size *= 2