1. 选择排序
"""
选择排序:
原理:
每轮比较, 都找到最小值所在的索引, 然后和 最小索引进行交换即可
"""
def selectSort(my_list):
"""
通过选择排序的思路, 对 列表元素 进行排序
:param my_list: 要进行排序的列表
:return:
"""
# 获取列表的长度
n = len(my_list)
# 开始每轮 每次的比较
# 外循环, 控制: 比较的轮数 假设n为5, 则 i的值: 0, 1, 2, 3
for i in range(n - 1): # 核心细节: 定义变量 min_index, 用于记录 (每轮)最小值的 索引
# 假设每轮的第1个值, 为: 最小值
min_index = i
# 内循环, 控制: 每轮比较的次数
for j in range(i + 1, n):
# 具体的比较过程: 如果当前元素 比 min_index 记录的元素还要小, 就用 min_index 记录住该元素的索引
if my_list[j] < my_list[min_index]:
min_index = j
# 走到这里, 说明1轮比较完毕, 我们要看 min_index的值有无发生改变, 改变了, 就是找到了 本轮的最小值
if min_index != i:
my_list[i], my_list[min_index] = my_list[min_index], my_list[i]
if __name__ == '__main__':
data_list = [7, 4, 8, 5, 2, 0, 1, 9, 3, 6]
print(f"排序前的顺序:{data_list}")
selectSort(data_list)
print(f"排序后的顺序:{data_list}")
控制台输出
排序前的顺序:[7, 4, 8, 5, 2, 0, 1, 9, 3, 6]
排序后的顺序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2. 堆排序
"""
堆排序:
将带排序序列放入大根堆,在将堆顶元素放到整个序列已排好序部分的最前面
然后重新调整排序部分为大根堆,直到排序完成
细节:
升序使用大根堆
降序使用小根堆
"""
def maxHeap(data_list, size, parent):
"""
调整一颗树为大根堆
:param data_list:
:param size:
:param parent:
:return:
"""
# 获取parent的左子树的节点数
leftNode = 2 * parent + 1
# 获取parent的右子树的节点数
rightNode = 2 * parent + 2
# 默认父节点最大
maxNode = parent
# 依次判断左子节点和右子节点, 找到最大数的索引
if leftNode < size and data_list[maxNode] < data_list[leftNode]:
maxNode = leftNode
if rightNode < size and data_list[maxNode] < data_list[rightNode]:
maxNode = rightNode
# 若最大的节点在判断完后不再是父节点, 说明最大的节点是左子结点或柚子节点
if maxNode != parent:
data_list[parent], data_list[maxNode] = data_list[maxNode], data_list[parent]
# 递归处理子树
maxHeap(data_list, size, maxNode)
def heapSort(data_list):
last = len(data_list) - 1
# 获取最后一个元素的父节点索引
parent = last // 2 - 1 if last % 2 == 0 else last // 2
# 从最后一个父节点向前一次调整
while parent >= 0:
maxHeap(data_list, len(data_list), parent)
parent -= 1
# 遍历区间 i 需要调整为大根堆的最后一个位置,依次减少
i = last
while i > 0:
data_list[0], data_list[i] = data_list[i], data_list[0]
# 重新将第0个位置调整为大根堆, i-1是最后要调整的位置,size 直接传入 i
maxHeap(data_list, i, 0)
i -= 1
if __name__ == '__main__':
data_list = [7, 4, 8, 5, 2, 0, 1, 9, 3, 6]
print(f"排序前的顺序:{data_list}")
heapSort(data_list)
print(f"排序后的顺序:{data_list}")
控制台输出
排序前的顺序:[7, 4, 8, 5, 2, 0, 1, 9, 3, 6]
排序后的顺序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3. 基数排序
"""
基数排序
是一种特殊的排序算法, 不需要在各元素之间比较大小,也不需要元素间交换位置
只需要将元素按照规则进行分类即可,完成排序
基本流程:
把所有数先按照个位存入相应的队列中,再依次取出所有队列中数, 然后按照百位,千位继续存取
要执行的轮数取决于最大的位数
平均时间复杂度 O(d(r+n))
其中 d 表示某个操作的固定次数, r 表示数据规模(通常表示为数组长度或集合大小)
n 也是数据规模的一部分,通常指基本操作如元素个数
"""
def radixSort(data_list):
"""
基数排序
:param data_list:
:return:
"""
# 获取数字最大数是几位的 比如 1234 这个数值 是 4位
# str(number) 将数字转为字符串
# int(str(number)) 将字符串转为数字
# str(number)[-i] 取出个位十位百位等 字符串切片 从后往前获取值 -1 表示最后一位
maxLen = len(str(max(data_list)))
# 创建嵌套列表作为队列
queues = [[] for i in range(0, 10)]
# 根据最大长度遍历轮数
for i in range(1, maxLen + 1):
# 遍历所有数值
for n in data_list:
try:
idx = int(str(n)[-i])
# 出现异常, 说明位数不足,则高位一定为0
except:
idx = 0
# 将数字追回到列表中
queues[idx].append(n)
# 清空列表 然后按队列顺序,存入顺序取出元素放回原序列中
data_list.clear()
for q in queues:
data_list.extend(q)
q.clear()
if __name__ == '__main__':
data_list = [7, 4, 8, 5, 2, 0, 1, 9, 3, 6]
print(f"排序前的顺序:{data_list}")
radixSort(data_list)
print(f"排序后的顺序:{data_list}")
控制台输出
排序前的顺序:[7, 4, 8, 5, 2, 0, 1, 9, 3, 6]
排序后的顺序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]