1. 程式人生 > >6種排序演算法的Python實現

6種排序演算法的Python實現

1.氣泡排序

思路:遍歷列表,每一輪每次比較相鄰兩項,將無序的兩項交換,下一輪遍歷比前一輪比較次數減1。

def bubble_sort(a_list):
    for passnum in range(len(a_list)-1, 0, -1):
        for i in range(passnum):
            if a_list[i] > a_list[i+1]:
                 a_list[i], a_list[i+1] = a_list[i+1], a_list[i]

改進:遍歷期間沒有交換,則認為已排序,可以停止。

def short_bubble_sort(a_list):
    exchanges = True
    passnum = len(a_list) - 1
    while passnum > 0 and exchanges:
        exchanges = False
        for i in range(passnum):
            if a_list[i] > a_list[i+1]:
                exchanges = True
                a_list[i], a_list[i+1] = a_list[i+1], a_list[i]
        passnum = passnum - 1

動畫演示:

2.選擇排序

思路:遍歷列表,每次遍歷選出最大的放在合適的位置。

def selection_sort(a_list):
    for fillslot in range(len(a_list)-1, 0, -1):
        position_max=0
        for location in range(1, fillslot+1):
            if a_list[location] > a_list[position_max]:
                position_max = location
        a_list[fillslot], a_list[position_max] = a_list[position_max], a_list[fillslot]

動畫演示:

3.插入排序

思路:每一步都將待插入的資料按大小插入到已排序的資料中的合適位置。

def insertion_sort(a_list):
    for index in range(1, len(a_list)):
        cur_value = a_list[index]
        pos = index
        while pos > 0 and a_list[pos-1] > cur_value:
            a_list[pos] = a_list[pos-1]
            pos = pos - 1
        a_list[pos] = cur_value

動畫演示:

4.希爾排序

思路:分解為多個子列表進行插入排序,不是連續分,而是通過增量。

def shell_sort(a_list):
    sublist_count = len(a_list)
    while sublist_count > 0:
        for start_position in range(sublist_count):
            gap_insertion_sort(a_list, start_position, sublist_count)
        sublistcount = sublistcount // 2

def gap_insertion_sort(a_list, start, gap):
    for i in range(start+gap, len(a_list), gap):
        current_value = a_list[i]
        position = i
        while position >= gap and a_list[position-gap] > current_value:
            a_list[position] = a_list[position-gap]
            position = position - gap
        a_list[position] = current_value

5.歸併排序

思路:分而治之,不斷拆分為一半,直至項數為0或1,然後排序合併。需要額外空間。

def merge_sort(a_list):
    if len(a_list) > 1:
        mid = len(a_list) // 2
        lefthalf = a_list[:mid]
        righthalf = a_list[mid:]
        merge_sort(lefthalf)
        merge_sort(righthalf)
        i=0
        j=0
        k=0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                a_list[k] = lefthalf[i]
                i = i + 1
            else:
                a_list[k] = righthalf[j]
                j = j + 1
            k=k+1
        while i < len(lefthalf):
            a_list[k] = lefthalf[i]
            i = i + 1
            k = k + 1
        while j < len(righthalf):
            a_list[k] = righthalf[j]
            j = j + 1
            k = k + 1

動畫演示:

6.快速排序

思路:與歸併一樣使用分而治之,不使用額外記憶體,特點是樞軸值。

def quick_sort(a_list):
    quick_sort_helper(a_list, 0, len(a_list)-1)

def quick_sort_helper(a_list, first, last):
    if first < last:
        splitpoint = partition(a_list, first, last)
        quick_sort_helper(a_list, first, splitpoint-1)
        quick_sort_helper(a_list, splitpoint+1, last)

def partition(a_list, first, last):
    pivotvalue = a_list[first]
    leftmark = first + 1
    rightmark = last
    done = False
    while not done:
        while leftmark <= rightmark and a_list[leftmark] <= pivotvalue:
            leftmark = leftmark + 1
        while a_list[rightmark] >= pivotvalue and rightmark >= leftmark:
            rightmark = rightmark -1
        if rightmark < leftmark:
            done = True
        else:
            a_list[leftmark], a_list[rightmark] = a_list[rightmark], a_list[leftmark]
    a_list[first], a_list[rightmark] = a_list[rightmark], a_list[first]

動畫演示:

說明: