ソート アルゴリズムの煮込み: クイック ソート、マージ ソート、バブル ソート

1. クイックソート(トップダウン)

1. クイックソートインプレースバージョン

最良の場合の時間計算量: O(nlogn)。ここで、logn は再帰のレベル数、n は再帰の各レベルの合計時間計算量です。
最悪の場合の時間計算量: O(n*n)

def quicksort_inplace(left,right): #子数组第一个元素和最后一个元素在原数组中的位置
    if left >= right: #递归终止条件
        return
    l,r,std = left, right, nums[left] #初始化左指针,右指针和基准值
    while r > l:    ##调整元素位置
        while nums[r] >= std and r > l:
            r -= 1
        tmp = nums[l]
        nums[l] = nums[r]
        nums[r] = tmp
        while nums[l] < std and r > l:
            l += 1
        tmp = nums[r]
        nums[r] = nums[l]
        nums[l] = tmp
    quicksort_inplace(left,l)
    quicksort_inplace(l+1,right)
    
nums = [5,3,6,4,1,2,8,7]
quicksort_inplace(0,len(nums)-1)
print(nums)

2. クイックソート時空間バージョン

最良の場合の時間計算量: O(nlogn) 未満

#快速排序
#没有if if else的用法
def quicksort_basic(arr):
    if len(arr) <= 1:
        return arr
    left = []
    right = []
    mid = []
    std = arr[len(arr) // 2]
    for x in arr:
        if x == std:
            mid.append(x)
        if x < std:
            left.append(x)
        #else:
        if x > std:
            right.append(x)
    return quicksort_basic(left) + mid + quicksort_basic(right)

2. マージソート(ボトムアップ)

思想:分割して征服せよ。分割統治では、配列内の要素が 1 つだけになるまでデータを 2 つの部分に再帰的に分割します。Merge は、ソートされた 2 つの配列を並べ替えます。新しい配列を返します。具体的には、マージの意味は次のとおりです。既に順序付けされた 2 つのリストがあると仮定し、 2 つのリストの開始要素を指すように2 つのポインタを設定し、メモリ領域を適用して新しい空のリストを作成し、要素のサイズを比較します。 2 つのポインターが指す要素を比較し、小さい方の要素を新しいリストに追加し、小さい方の要素を新しいリストに追加します。一方のリストのすべてのデータが追加されるまで、もう一方のリストの残りのデータを新しいリストに順番に追加します。これは、2 つの順序付きリストを新しい順序付きリストにマージするメソッドを実装します。

クイック ソートと比較して、マージの時間計算量はより安定しています。O(nlogn) のままです。ここで、logn は再帰レベルの数、n は再帰の各レベルの合計時間計算量です。

#归并排序
nums = [5,3,6,4,1,2,8,7]
def merge_sort(nums):
    if len(nums) <= 1:
        return nums
    left_arr = merge_sort(nums[0:len(nums) // 2])
    right_arr = merge_sort(nums[len(nums) // 2:])
    return merge(left_arr,right_arr)

def merge(left_arr,right_arr):
    rst = []
    pointer1 = 0
    pointer2 = 0
    while pointer1 < len(left_arr) and pointer2 < len(right_arr):
        if left_arr[pointer1] <= right_arr[pointer2]:
            rst.append(left_arr[pointer1])
            pointer1 += 1
        else:
            rst.append(right_arr[pointer2])
            pointer2 += 1
    return rst + right_arr[pointer2:] + left_arr[pointer1:] #技巧:right_arr[pointer2:]中加了冒号就不会报索引超出index的错误
        
rst = merge_sort(nums) 
print(rst)   

3. バブルソーティング

基本原理: 2 層の for ループを使用して、各外側ループは、順序付けされた要素の先頭にある順序付けされていない要素に最小の要素を配置できます 最悪の時間計算量 : O(
n *n)

#冒泡排序
nums = [5,3,6,4,1,2,8,7]
def bubbleSort(nums):
    for i in range(len(nums)):
        for j in range(i+1,len(nums)):
            if nums[j] < nums[i]:
                tmp = nums[j]
                nums[j] = nums[i]
                nums[i] = tmp      
bubbleSort(nums) 
print(nums)   

参照:
[Python アルゴリズム シリーズ 2] クイック ソート アルゴリズム
クイック ソート & マージ ソート - 時間計算量分析
クイック ソートとマージ ソート
Python がマージ ソートを実装

おすすめ

転載: blog.csdn.net/Rolandxxx/article/details/131404824