算法與數據結構:歸併排序(python實現)

歸併排序

用下邊例子來

 

level 0   8 6 2 3 1 5 7 4

leve 1    8 6 2 3           1 5 7 4

leve 2    8 6     2 3           1 5     7 4

leve 3    8    6    2    3          1     5    7    4

先將這組數分組,每次在中間分開,知道分成單個數位爲止,然後歸併。

從第三層爲第二層歸併

leve 2    6 8      2 3          1 5       4 7     這樣就分出來四個有序的序列

再到leve1 層

leve 1    2 3 6 8         1 4 5 7     形成兩個有序的序列

再到leve0

leve0 1 2 3 4 5 6 7 8

就得出了想要的結果。

圖解:

 

代碼:

a=[8, 2, 6, 3, 7, 2, 8, 5, 5, 5, 3, 8, 3, 4, 4]
def merge(arr, l, mid, r):
    aux=[]
    for c in range(l,r+1):
        aux.append(arr[c])
    i=l
    j=mid+1
    for k in range(l,r+1):
        if i > mid:
            arr[k] = aux[j - l]
            j+=1
        elif j > r:
            arr[k] = aux[i - l]
            i+= 1
        elif aux[i-l] <= aux[j-l]:
            arr[k]=aux[i-l]
            i+=1
        else:
            arr[k] = aux[j-l]
            j+=1
    return arr
def mergeSort1(arr,l,r):
    if  l>=r:
        return None
    mid = (l+r)/2
    mergeSort1(arr, l, mid)
    mergeSort1(arr, mid+1, r)
    merge(arr, l, mid, r)
    return arr
def mergeSort(arr):
    arr=mergeSort1(arr,0,len(arr)-1)
    return arr
print mergeSort(a)

其中mege可以修改爲下邊

def merge(arr,l,mid,r):
    ar=[]
    lt=l
    rt=mid+1
    while lt <= mid and rt <= r:
       if arr[lt] < arr[rt]:
           ar.append(arr[lt])
           lt+=1
       else:
           ar.append(arr[rt])
           rt+=1
    if  rt <= r:
        ar.extend(arr[rt:r+1])
    if lt <= mid:
        ar.extend(arr[lt:mid + 1])
    arr[l:r+1]=ar
    return arr

不再原地修改,直接將新生成的空間返回:

def merge(left,right):
    ar=[]
    mid =len(left)-1
    r = len(right)-1
    lt=0
    rt=0
    while lt <= mid and rt <= r:
       if left[lt] < right[rt]:
           ar.append(left[lt])
           lt+=1
       else:
           ar.append(right[rt])
           rt+=1
    if  rt <= r:
        ar.extend(right[rt:r+1])
    if lt <= mid:
        ar.extend(left[lt:mid + 1])
    return ar
def mergeSort(arr):
    l=0
    r=len(arr)-1
    if l >=r:
        return arr
    mid = (r+l)//2
    left = mergeSort(arr[l:mid+1])
    right = mergeSort(arr[mid+1:r+1])
    arr = merge(left,right)
    return arr
a=[1,3,5,3,6,7,8]

print(mergeSort(a))

歸併排序當右邊的第一個元素大於左邊的最後一個元素,可以直接合並,提前中止,修改代碼如下:

def merge(left,right):
    ar=[]
    mid =len(left)-1
    r = len(right)-1
    lt=0
    rt=0
    while lt <= mid and rt <= r and left[mid] > right[rt]:
       if left[lt] < right[rt]:
           ar.append(left[lt])
           lt+=1
       else:
           ar.append(right[rt])
           rt+=1

    if lt <= mid:
        ar.extend(left[lt:mid + 1])
    if rt <= r:
        ar.extend(right[rt:r + 1])
    return ar

參考文獻:

1、慕課https://coding.imooc.com/class/71.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章