1. 程式人生 > >python實現堆排序、快速排序、歸併排序

python實現堆排序、快速排序、歸併排序

堆排序

 

 

快速排序

    快速排序一般選擇序列的兩頭位置,分別記為low和high,第一遍排序將low指標對應的值作為一個key值,試圖將大於key值的放在它的右邊,小於key值的放在左邊。具體實現是以key為標準,將high指標依次向左移動,直到找到一個high對應的值小於key值為止,將此時high指標對應的值和key值互換;然後以此時key值對應的指標為對照標準(即此時high的位置),對比key值和此時low指標對應的值大小,如果low對應的值大於key值,則low對應的值和key互換,否則將low指標依次右移一個單位,直到low=high或者找到一個low指標對應的值大於key值。經過以上第一輪排序,原來的序列被key值分為了兩部分,此時呼叫遞迴方法將這兩個子序列分別排序,直到最終變成一個有序序列。時間複雜度為:nlogn。

方法一(按照步驟,將每個階段分開寫的):

def swap(list,a,b):
    c=list[a]
    list[a]=list[b]
    list[b]=c
    return list
def pivot_sperate(list,low,high):
    key=list[low]
    while low < high:
        while low<high and list[high]>key:
            high-=1
        list=swap(list,low,high)
        while low<high and list[low]<key:
            low+=1
        list=swap(list,high,low)
    return low

def quick_sort(list,low,high):
    if low<high:
        pivot=pivot_sperate(list,low,high)
        quick_sort(list,low,pivot-1)
        quick_sort(list,pivot+1,high)
    return list

list=[7,4,2,1,5,3,6,9,8,10]
last_list=quick_sort(list,0,len(list)-1)
print(last_list)

方法二(與方法一思想一樣,程式碼融合在一起了):

def QuickSort(myList,start,end):
    #判斷low是否小於high,如果為false,直接返回
    if start < end:
        i,j = start,end
        #設定基準數
        base = myList[i]

        while i < j:
            #如果列表後邊的數,比基準數大或相等,則前移一位直到有比基準數小的數出現
            while (i < j) and (myList[j] >= base):
                j = j - 1

            #如找到,則把第j個元素賦值給第個元素i,此時表中i,j個元素相等
            myList[i] = myList[j]

            #同樣的方式比較前半區
            while (i < j) and (myList[i] <= base):
                i = i + 1
            myList[j] = myList[i]
        #做完第一輪比較之後,列表被分成了兩個半區,並且i=j,需要將這個數設定回base
        myList[i] = base

        #遞迴前後半區
        QuickSort(myList, start, i - 1)
        QuickSort(myList, j + 1, end)
    return myList


myList = [7,4,2,1,5,3,6,9,8,10]
print("Quick Sort: ")
QuickSort(myList,0,len(myList)-1)
print(myList)

歸併排序

歸併排序演算法是採用分治法的典型應用,將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。

工作原理如下:

第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列

第二步:設定兩個指標,最初位置分別為兩個已經排序序列的起始位置

第三步:比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置

重複步驟3直到某一指標超出序列尾

將另一序列剩下的所有元素直接複製到合併序列尾

例:設有數列{6,202,100,301,38,8,1}

初始狀態:6,202,100,301,38,8,1

第一次歸併後:{6,202},{100,301},{8,38},{1},比較次數:3;

第二次歸併後:{6,100,202,301},{1,8,38},比較次數:4;

第三次歸併後:{1,6,8,38,100,202,301},比較次數:4;

總的比較次數為:3+4+4=11;

def MergeSort(lists):
    if len(lists) <= 1:
        return lists
    num = int( len(lists) / 2 )
    left = MergeSort(lists[:num])
    right = MergeSort(lists[num:])
    return Merge(left, right)
def Merge(left,right):
    r, l=0, 0
    result=[]
    while l<len(left) and r<len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result

if __name__=='__main__':
    list0=[1, 2, 3, 4, 5, 6, 7, 90, 21, 23, 45]
    list=MergeSort(list0)
    print (list)