python希爾排序、歸併排序

希爾排序,也稱遞減增量排序算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序算法。

希爾排序的基本思想是:先將整個待排序的記錄序列分割成爲若干子序列分別進行直接插入排序,待整個序列中的記錄"基本有序"時,再對全體記錄進行依次直接插入排序。

希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因DL.Shell於1959年提出而得名。 希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
 

 

代碼如下:

def shell_sort(alist):
    '''
    希爾排序
    :param alist:
    :return:
    '''
    n = len(alist)
    gap = n // 2
    # gap變化到0之前,插入算法執行的次數
    while gap > 0:
        # 插入算法,與普通的插入算法就是gap步長的不同
        for j in range(gap,n):
            i = j
            while i > 0 and alist[i] < alist[i - gap]:
                alist[i],alist[i-gap] = alist[i-gap],alist[i]
                i -= gap
        # 縮短gap步長
        gap //= 2
if __name__ == '__main__':
    li = [54,26,93,17,77,31,44,55,28]
    print('排序前',li)
    shell_sort(li)
    print('排序後',li)

運行結果:

排序前 [54, 26, 93, 17, 77, 31, 44, 55, 28]
排序後 [17, 26, 28, 31, 44, 54, 55, 77, 93]

歸併排序

歸併排序(英語:Merge sort,或mergesort),是創建在歸併操作上的一種有效的排序算法。該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。

1、歸併排序原理

     歸併排序採用分而治之的原理:

     一、將一個序列從中間位置分成兩個序列;

     二、在將這兩個子序列按照第一步繼續二分下去;

     三、直到所有子序列的長度都爲1,也就是不可以再二分截止。這時候再兩兩合併成一個有序序列即可。

2、原理圖

  

代碼如下:

def merge(left_li,right_li):
    '''
    排序合併
    :param left_li:
    :param right_li:
    :return:
    '''
    left_pointer,right_pointer = 0,0
    result = []
    while right_pointer < len(left_li) and left_pointer < len(right_li):
        if left_li[right_pointer] < right_li[left_pointer]:
            result.append(left_li[right_pointer])
            right_pointer += 1
        else:
            result.append(right_li[left_pointer])
            left_pointer += 1
    if right_pointer == len(left_li):
        for i in right_li[left_pointer:]:
            result.append(i)
    else:
        for i in left_li[right_pointer:]:
            result.append(i)

    return result

def merge_sort(alist):
    '''
    分組整合
    :param alist:
    :return:
    '''
    n = len(alist)
    if n <= 1:
        return alist
    mid = n // 2
    left_li = merge_sort(alist[:mid])
    right_li = merge_sort(alist[mid:])
    return merge(left_li,right_li)

if __name__ == '__main__':
    li = [54, 26, 93, 17, 77, 31, 44, 55, 28]
    print('排序前',li)
    print('排序後',merge_sort(li))

運行結果:

排序前 [54, 26, 93, 17, 77, 31, 44, 55, 28]
排序後 [17, 26, 28, 31, 44, 54, 55, 77, 93]

 

 

 

 

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