# -*- 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