簡單排序算法Python(只寫了代碼,僅供自己參考)

# -*- coding: utf-8 -*-
# 參考各位大佬的寫法整理了一下,便於自己對簡單排序算法的理解


def bubble_sort(input_list):
    """冒泡排序"""
    length = len(input_list)
    if length < 2:
        return input_list
    for i in range(length):
        for j in range(length - 1 - i):
            if input_list[j + 1] < input_list[j]:
                input_list[j + 1], input_list[j] = input_list[j], input_list[j + 1]
    return input_list


def select_sort(input_list):
    """選擇排序"""
    length = len(input_list)
    if length < 2:
        return input_list
    for i in range(length):
        minIndex = i  # 初始默認minIndex爲未排序列中最小元素對應的索引
        for j in range(i + 1, length):
            if input_list[j] < input_list[minIndex]:  # 如果找到更小元素,進行交換
                input_list[j], input_list[minIndex] = input_list[minIndex], input_list[j]
    return input_list


def quick_sort(input_list):
    """快速排序"""
    # 這個遞歸的快排會更好理解一些
    if len(input_list) >= 2:
        mid = input_list[len(input_list) // 2]
        left, right = [], []
        input_list.remove(mid)
        for num in input_list:
            if num >= mid:
                right.append(num)
            else:
                left.append(num)
        return quick_sort(left) + [mid] + quick_sort(right)
    else:
        return input_list


def insert_sort(input_list):
    """插入排序"""
    length = len(input_list)
    if length < 2:
        return input_list
    for i in range(length):
        j = i
        target = input_list[i]  # target要進行插入的元素
        while j > 0 and input_list[j - 1] > target:  # 尋找插入位置
            input_list[j] = input_list[j - 1]
            j = j - 1
        input_list[j] = target
    return input_list


def heap_sort(input_list):
    """堆排序"""

    def sift_down(input_list, father, end):  # 讓父節點始終比左右子節點(如果右節點存在的話)的值要大
        while True:
            # 交換之後可能造成被交換的孩子節點作爲父節點不再滿足堆的性質,因此需要重新對交換的孩子節點進行堆初始化
            left_child = 2 * father + 1  # 父節點左孩子節點下標
            if left_child > end:  # 孩子節點不一定還有孩子節點
                break
            # 如果節點的右孩子存在且大於左孩子時,此時,右孩子爲孩子節點中的最大,交換時此右節點與父節點交換
            # 否則,父節點只有左孩子或者左孩子比右孩子要小,此時,左孩子是孩子節點中最大的,交換時此左節點與父節點交換
            if left_child + 1 <= end and input_list[left_child + 1] > input_list[left_child]:
                left_child = left_child + 1
            # 若上一個if語句執行,則以下代碼是右子節點與父節點交換,否則,爲左子節點與父節點交換
            if input_list[left_child] > input_list[father]:
                input_list[left_child], input_list[father] = input_list[father], input_list[left_child]
                father = left_child  # 被調換的子節點重新作爲父節點進行調整操作
            else:
                break

    length = len(input_list)
    first = length // 2 - 1  # 最後一個有孩子的節點的下標
    for i in range(first, -1, -1):  # 從最後一個有子節點的節點開始往上調整最大堆
        sift_down(input_list, i, length - 1)
    for head_end in range(length - 1, 0, -1):
        input_list[head_end], input_list[0] = input_list[0], input_list[head_end]  # 頭尾對調,同時堆開始變小
        sift_down(input_list, 0, head_end - 1)  # father=0, 表示交換以後從根節點開始往下調整
    return input_list


def count_sort(input_list):
    """計數排序"""
    length = len(input_list)
    if length < 2:
        return input_list
    max_num = max(input_list)
    count = [0] * (max_num + 1)
    for element in input_list:
        count[element] += 1  # 間接使用索引來存儲數
    input_list.clear()
    for i in range(max_num + 1):  # 元素[0, 1, 2, ..., max_num]
        # if count[i] != 0:  # 如果沒有重複元素,用這個也可以
        #     input_list.append(i)
        for j in range(count[i]):  # count[i]表示元素i出現的次數,如果有多次,重複追加
            input_list.append(i)
    return input_list
    # 下面這種代碼思想也可以達到相同的目的,只不過中間涉及到元素間的比較,與計數排序的思想稍有差異。
    # count = [0] * length
    # for i in range(length):
    #     p = 0
    #     q = 0
    #     for j in range(length):
    #         # 全表查找比input_list[i]小的元素個數p;q是爲了保證相同元素重複出現時仍然能夠正常排序
    #         if input_list[j] < input_list[i]:  # 這塊的元素比較使得它算不上真正意義上的計數排序
    #             p += 1
    #         elif input_list[j] == input_list[i]:
    #             q += 1
    #     # count[p] = input_list[i]
    #     for k in range(p, p + q):  # 如果沒有重複元素,最終可得q=1,這裏其實就可以寫成 count[p] = input_list[i] 了
    #         count[k] = input_list[i]
    # return count


def radix_sort(input_list, radix=10):
    """基數排序"""
    # import math
    # K = math.ceil(math.log(max(input_list), radix))  # 用K位數可表示任意整數
    K = 1  # 也可不用 import math 模塊
    for element in input_list:
        if element >= radix ** K:
            K += 1
    # K表示最大數的位數,比如最大數爲897,則K=3
    bucket = [[] for i in range(radix)]  # 不能用 [[]]*radix (看完下面幾條語句你就會明白爲什麼)
    # bucket = [[]] * radix  # [[], [], [], [], [], [], [], [], [], []]
    # >>> aa = [[]] * 10  # 一改具改
    # >>> bb = [[] for i in range(10)]
    # >>> aa == bb  # 儘管有
    # True
    # >>> aa[0] is aa[1]
    # True
    # >>> bb[0] is bb[1]  # 但是
    # False
    # [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    # [[50], [], [2], [3], [44, 4], [5, 15], [36, 26, 46], [47, 27], [38, 48], [19]]
    # [50, 2, 3, 44, 4, 5, 15, 36, 26, 46, 47, 27, 38, 48, 19]
    # [[2, 3, 4, 5], [15, 19], [26, 27], [36, 38], [44, 46, 47, 48], [50], [], [], [], []]
    # [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
    for i in range(K):  # K次循環
        for val in input_list:
            bucket_index = val % (radix ** (i + 1)) // (radix ** i)  # 把val放到bucket_index對應的這個桶
            # example 4789 % 10**3 // 10**2 == 7
            bucket[bucket_index].append(val)  # 析取整數第K位數字 (從低到高, 個十百千...)
        input_list.clear()
        for each in bucket:
            input_list.extend(each)  # 桶合併
        bucket = [[] for i in range(radix)]
    return input_list


# 示例:
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("冒泡排序:", bubble_sort(input_list))
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("選擇排序:", select_sort(input_list))
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("快速排序:", quick_sort(input_list))
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("插入排序:", insert_sort(input_list))
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("  堆排序:", heap_sort(input_list))
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("計數排序:", count_sort(input_list))
input_list = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
print("基數排序:", radix_sort(input_list))

 

"D:\Program Files\Python36\python3.exe" D:/MyProject/Python/workspace/sorting_algorithm.py
冒泡排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
選擇排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
快速排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
插入排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
  堆排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
計數排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
基數排序: [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

Process finished with exit code 0

 

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