小魚要學數據結構與算法(基於python)—Day14歸併排序和快速排序

排序和查找

在這裏插入圖片描述

一、知識概覽

本章主要講解六種排序算法中的歸併排序和快速排序,知識概覽如下。

1.1 歸併排序

歸併排序

1.2 快速排序

快速排序

歸併排序的重點在於合,而快速排序的重點在於分,下面是分裂過程:
分裂過程

二 代碼實現

2.1 歸併排序

#歸併排序
def mergeSort(alist):
    if len(alist)>1:
        mid =len(alist)//2
        lefthalf=alist[:mid]
        righthalf=alist[mid:]
        mergeSort(lefthalf)
        mergeSort(righthalf)

        i=j=k=0
        while i<len(lefthalf) and j<len(righthalf):
            if lefthalf[i]<righthalf[j]:
                alist[k]=lefthalf[i]
                i=i+1
            #拉鍊式交錯把左右半部從小到大歸併到結果列表中
            else:
                alist[k]=righthalf[j]
                j=j+1
            k=k+1
            #歸併左半部剩餘項
        while i<len(lefthalf):
            alist[k]=lefthalf[i]
            i=i+1
            k=k+1
            #歸併右半部剩餘項
        while j<len(righthalf):
            alist[k]=righthalf[j]
            j=j+1
            k=k+1

測試:

alist=[54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)

輸出:

[17, 20, 26, 31, 44, 54, 55, 77, 93]

2.2 更pythonic的歸併排序

#更pythonic的歸併排序
def mergeSort2(alist):
    #遞歸結束條件
    if len(alist)<=1:
        return alist
    #分解問題,並遞歸調用
    middle=len(alist)//2
    left=mergeSort2(alist[:middle])#左半部分排好序
    right=mergeSort2(alist[middle:])#右半部分排好序
    #合併左右半部分,完成排序
    merged=[]
    while left and right:#只要左右半部分都還有數據就進行合併
        if left[0]<=right[0]:#左半部分首部和右半部分首部進行對比
            merged.append(left.pop(0))#哪個小就添加到前面,同時把它刪除掉
        else:
            merged.append(right.pop(0))
    #循環後可能有剩也可能沒有
    merged.extend(right if right else left)#無論左右只要還有剩的,就歸併到列表的後面
    return merged

測試:

alist=[54,26,93,17,77,31,44,55,20]
mergeSort2(alist)
print(alist)

測試

alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
u=mergeSort2(alist)
print(u)

輸出

[17, 20, 26, 31, 44, 54, 55, 77, 93]

2.3 快速排序

# 快速排序
def quickSort(alist):
    quickSortHelper(alist, 0, len(alist) - 1)


def quickSortHelper(alist, first, last):
    if first < last:  # 基本結束條件
        # 分裂
        splitpoint = partition(alist, first, last)
        quickSortHelper(alist, first, splitpoint - 1)
        quickSortHelper(alist, splitpoint + 1, last)


def partition(alist, first, last):
    # 選定中值
    pivotvalue = alist[first]
    # 左右標初值
    leftmark = first + 1
    rightmark = last
    done = False
    while not done:
        while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
            leftmark = leftmark + 1
        while leftmark <= rightmark and alist[rightmark] >= pivotvalue:
            rightmark = rightmark - 1
        if rightmark < leftmark:
            done = True
        else:
            # 左右標值交換
            temp = alist[leftmark]
            alist[leftmark] = alist[rightmark]
            alist[rightmark] = temp
    # 中值就位
    temp = alist[first]
    alist[first] = alist[rightmark]
    alist[rightmark] = temp
    return rightmark  # 中值點也是分裂點


alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
quickSort(alist)
print(alist)

輸出

[17, 20, 26, 31, 44, 54, 55, 77, 93]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章