python-选择排序

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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值