【排序算法】用python實現常見的排序算法

目前實現了冒泡排序、選擇排序、插入排序、希爾排序、歸併排序和快速排序等常見算法。

1. 冒泡排序

通過兩層循環實現排序,每輪內循環實現外層子序列中最大/最小值的浮出。

def bubbleSort(nums:list):

    for i in range(len(nums)-1):
        for j in range(i+1, len(nums)):
            if nums[j] < nums[i]:
                nums[i], nums[j] = nums[j],  nums[i]
    return nums

# 一種優化方案:若某輪內循環詞序不變提前退出
def bubbleSort2(nums:list):
    exchange = True
    for i in range(len(nums)-1):
        if not exchange:
            return nums
        exchange = False
        for j in range(i+1, len(nums)):
            if nums[j] < nums[i]:
                exchange = True
                nums[i], nums[j] = nums[j],  nums[i]
    return nums
2. 選擇排序

冒泡排序的優化,迴避了每兩個數字對比後的交換過程,在每輪內循環中,只需記錄下子序列中最大值的位置,循環結束後再交換一次即可。

def selectionSort(nums:list):
    for i in range(len(nums)-1):
        smallIndex = i
        for j in range(i+1, len(nums)):
            if nums[j] < nums[smallIndex]:
                smallIndex = j
        nums[i], nums[smallIndex] = nums[smallIndex], nums[i]
    return nums
3. 插入排序

效仿摸牌的插入過程,在實現時並未直接從空列表開始增長,而是在原有序列上進行臨接位置的騰挪。

def insertSort(nums:list):

    for i in range(1, len(nums)):
        value = nums[i]
        index = i
        while index > 0 and nums[index-1] > value:
            nums[index] = nums[index-1]
            index -= 1
        if index != i:
            nums[index] = value
    return nums
4. 希爾排序

插入排序的優化,通過在分段子序列上不斷的進行插入排序,使得整個序列不斷有序。

def shellSort(nums:list):
    sublistcount = len(nums) // 2
    while sublistcount > 0:
        for startpositon in range(sublistcount):
            gapInsertSort(nums, startpositon, sublistcount)
            print("After increment of size {}, the list is {}.".format(sublistcount, nums))
        sublistcount //= 2


def gapInsertSort(alist, start, gap):
    for i in range(start+gap, len(alist), gap):
        currentValue = alist[i]
        while i > 0 and alist[i-gap] > currentValue:
            alist[i] = alist[i-gap]
            i -= gap
        alist[i] = currentValue
5. 歸併排序

利用分治思想,實現序列排序結果和一對子序列排序結果間的遞歸操作。注意在一對子序列排序的對比過程中,需要分別採用一個動態指針。

def mergeSort(nums:list):

    if len(nums) > 1:
        mid_index = len(nums) // 2
        left_nums = nums[:mid_index]   # 切片爲deep_copy
        right_nums = nums[mid_index:]

        mergeSort(left_nums)
        mergeSort(right_nums)

        i, j = 0, 0
        while i < len(left_nums) and j < len(right_nums):
            if left_nums[i] < right_nums[j]:
                nums[i+j] = left_nums[i]
                i += 1
            else:
                nums[i+j] = right_nums[j]
                j += 1

        if i == len(left_nums):
            nums[i+j:] = right_nums[j:]

        if j == len(right_nums):
            nums[i+j:] = left_nums[i:]

6. 快速排序

同樣利用遞歸思想,每輪找到樞軸值的排序索引,並據此將序列分爲大於樞軸值的子序列和小於樞紐值的子序列。

def quickSort(nums:list):
    quickSortIter(nums, 0, len(nums)-1)


def quickSortIter(nums, first, last):

    if first < last:
        left_marker = first+1
        right_marker = last
        pivot = nums[first]

        while left_marker < right_marker:

            while nums[left_marker] <= pivot and left_marker <= right_marker  and left_marker < last:
                left_marker += 1

            while nums[right_marker] >= pivot and left_marker <= right_marker and right_marker > 0:
                right_marker -= 1

            if left_marker < right_marker:   # 防止left_marker和right_marker交錯時發生錯誤交換
                nums[left_marker], nums[right_marker] = nums[right_marker], nums[left_marker]

        if nums[right_marker] < pivot:
            nums[right_marker], nums[first] = pivot, nums[right_marker]

        quickSortIter(nums, first, right_marker-1)
        quickSortIter(nums, right_marker+1, last)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章