ホームページ  >  記事  >  バックエンド開発  >  プログラマーがマスターしなければならないソート アルゴリズムのトップ 10 (パート 2)

プログラマーがマスターしなければならないソート アルゴリズムのトップ 10 (パート 2)

Python当打之年
Python当打之年転載
2023-08-15 14:53:111487ブラウズ


書籍の問題の紹介

ソートアルゴリズムすべてのプログラマーがマスターした後に必ず持っていると言えるでしょう。 、その原理と実装を理解する必要があります。.以下は、学習を容易にする、最も一般的に使用される 10 個の並べ替えアルゴリズムの Python 実装の紹介です。 . .


#01 バブル ソート交換ソート
#02 クイック ソート交換ソート


03 選択ソート - 選択クラスのソート
04 ヒープ ソート - 選択クラスのソート


# 05 インサーションソート - インサーションクラスソート

06 ヒルソート - インサーションクラスソート

##07 マージソート - マージソートソート

##08 個数ソート - 分布ソート

#

09 基数ソート - 分布ソート

10 バケット ソート - 分布クラス ソート



06
ヒルソート
HillSort (シェル ソート): は挿入ソートの一種で、「ディミニシング インクリメント ソート」とも呼ばれます) は、ダイレクト ソートのより効率的かつ改良されたバージョンです。挿入ソートアルゴリズム。

#アルゴリズム原理:
n
  • より小さい整数のギャップ (ギャップをステップ サイズと呼びます) をとり、並べ替える要素をいくつかのグループに分割します後続では、距離がギャップの倍数であるすべてのレコードが同じグループに配置されます。

    各グループ内の要素に対して直接挿入ソートを実行します。今回は、ソートが完了すると、各グループの要素が順序付けされます。
  • ギャップ値を減らし、上記のグループ化とソートを繰り返します
  • 上記の操作を繰り返し、gap=1 でソート終了
  • ##

コードは次のとおりです:
'''希尔排序'''
def Shell_Sort(arr):
    # 设定步长,注意类型
    step = int(len(arr) / 2)
    while step > 0:
        for i in range(step, len(arr)):
            # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置
            while i >= step and arr[i - step] > arr[i]:
                arr[i], arr[i - step] = arr[i - step], arr[i]
                i -= step
        step = int(step / 2)
    return arr

arr = [29, 63, 41, 5, 62, 66, 57, 34, 94, 22]
result = Shell_Sort(arr)
print('result list: ', result)
# result list: [5, 22, 29, 34, 41, 57, 62, 63, 66, 94]


#07
並べ替えの結合
##マージ ソート : は、マージ操作に基づいた効果的で安定したソート アルゴリズムです。このアルゴリズムは非常に典型的なものです。分割統治法 (Divide and Conquer) の適用。これは、順序付けられたサブシーケンスをマージして、完全に順序付けされたシーケンスを取得します。

#アルゴリズム原理:
  • そのサイズが 2 つの並べ替えられたシーケンスの合計になるように、スペースを適用します。このスペースは、マージされたシーケンスを保存するために使用されます。シーケンス

    は 2 つのインデックスを設定します。最初の
  • インデックス
  • 位置は、2 つの並べ替えられたシーケンス

    ## の開始位置です。 # 2 つの

    インデックス
  • が指す要素を比較し、比較的小さい要素を選択してマージ スペースに配置し、
  • インデックス

    を次の場所に移動します。次の位置##特定の index

    がシーケンスの終わりを超えるまで前のステップを繰り返します
  • #他のシーケンスの残りのすべての要素をマージされたシーケンスの最後に直接コピーします

代码如下:
'''归并排序'''def Merge(left, right):
    arr = []
    i = j = 0
    while j < len(left) and  i < len(right):
        if left[j] < right[i]:
            arr.append(left[j])
            j += 1
        else:
            arr.append(right[i])
            i += 1
    if j == len(left):
        # right遍历完
        for k in right[i:]:
            arr.append(k)
    else:
        # left遍历完
        for k in left[j:]:
            arr.append(k)
    return arr

def Merge_Sort(arr):
    # 递归结束条件
    if len(arr) <= 1:
        return arr
    # 二分
    middle = len(arr) // 2
    left = Merge_Sort(arr[:middle])
    right = Merge_Sort(arr[middle:])
    # 合并
    return Merge(left, right)

arr = [27, 70, 34, 65, 9, 22, 47, 68, 21, 18]
result = Merge_Sort(arr)
print(&#39;result list: &#39;, result)
# result list: [9, 18, 21, 22, 27, 34, 47, 65, 68, 70]

08
计数排序
计数排序(Count sort):是一个非基于比较的排序算法,它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。

算法原理:
  • 找出待排序的数组中最大和最小的元素

  • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项

  • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)

  • 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1


代码如下:
&#39;&#39;&#39;计数排序&#39;&#39;&#39;
def Count_Sort(arr):
    max_num = max(arr)
    min_num = min(arr)
    count_num = max_num - min_num + 1
    count_arr = [0 for i in range(count_num)]
    res = [0 for i in range(len(arr))]
    # 统计数字出现的次数
    for i in arr:
        count_arr[i - min_num] += 1
    # 统计前面有几个比自己小的数
    for j in range(1, count_num):
        count_arr[j] = count_arr[j] + count_arr[j - 1]
    # 遍历重组
    for k in range(len(arr)):
        res[count_arr[arr[k] - min_num] - 1] = arr[k]
        count_arr[arr[k] - min_num] -= 1
    return res

arr = [5, 10, 76, 55, 13, 79, 5, 49, 51, 65, 30, 5]
result = Count_Sort(arr)
print(&#39;result list: &#39;, result)
# result list: [5, 5, 5, 10, 13, 30, 49, 51, 55, 65, 76, 79]

09
基数排序
基数排序(radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

算法原理(以LSD为例):
  • 根据个位数的数值,遍历列表将它们分配至编号0到9的桶子中

  • 将这些桶子中的数值重新串接起来

  • 根据十位数的数值,遍历列表将它们分配至编号0到9的桶子中

  • 再将这些桶子中的数值重新串接起来


代码如下:
&#39;&#39;&#39;基数排序&#39;&#39;&#39;
def Radix_Sort(arr):
    max_num = max(arr)
    place = 0
    while 10 ** place <= max_num:
        # 创建桶
        buckets = [[] for _ in range(10)]
        # 分桶
        for item in arr:
            pos = item // 10 ** place % 10
            buckets[pos].append(item)
        j = 0
        for k in range(10):
            for num in buckets[k]:
                arr[j] = num
                j += 1
        place += 1
    return arr

arr = [31, 80, 42, 47, 35, 26, 10, 5, 51, 53]
result = Radix_Sort(arr)
print(&#39;result list: &#39;, result)
# result list: [5, 10, 26, 31, 35, 42, 47, 51, 53, 80]

10
桶排序
桶排序 (Bucket sort)或所谓的箱排序:划分多个范围相同的桶区间,每个桶自排序,最后合并,桶排序可以看作是计数排序的扩展。

算法原理:
  • 计算有限桶的数量

  • 逐个桶内部排序

  • 遍历每个桶,进行合并


代码如下:
&#39;&#39;&#39;桶排序&#39;&#39;&#39;
def Bucket_Sort(arr):
    num = max(arr)
    # 列表置零
    pre_lst = [0] * num
    result = []
    for data in arr:
        pre_lst[data - 1] += 1
    i = 0
    while i < len(pre_lst): # 遍历生成的列表,从小到大
        j = 0
        while j < pre_lst[i]:
            result.append(i + 1)
            j += 1
        i += 1
    return result

arr = [26, 53, 83, 86, 5, 46, 5, 72, 21, 4, 75]
result = Bucket_Sort(arr)
print(&#39;result list: &#39;, result)
# result list: [4, 5, 5, 21, 26, 46, 53, 72, 75, 83, 86]

以上がプログラマーがマスターしなければならないソート アルゴリズムのトップ 10 (パート 2)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はPython当打之年で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。