经典排序方法(python),桶排序, 基数排序, 堆排序

桶排序

思路:

  • 设置一定数量的数组当作空桶;
  • 遍历输入数据,并且把数据一个一个放到对应的桶里去;
  • 对每个不是空的桶进行排序,内部可使用各种排序方法;
  • 从不是空的桶里把排好序的数据拼接起来

代码:

# 桶排序
def bucket_sort(num:list[int], bucket_size:int=5) -> list[int]:
    max_val, min_val = max(num), min(num)
    # 数据分为 bucketCount 组,这一个是根据每组的数量决定的
    bucket_count = (max_val - min_val) // bucket_size + 1
    buckets = [[] for _ in range(bucket_count)] # 二维桶
    # 利用函数映射将各个数据放入对应的桶中
    for i in num:
        buckets[(i - min_val) // bucket_size].append(i)
    # 清空 num
    num.clear()
    # 对每一个二维桶中的元素进行排序
    for bucket in buckets:
        #print(bucket)
        insertion_sort(bucket) # 假设使用插入排序
        num.extend(bucket)  # 将排序好的桶依次放入到 num 中
    return num

# 插入排序 
def insertion_sort(num: list[int]) -> None:
    length = len(num)
    for i in range(1, length):
        for j in range(i, 0, -1):
            if num[j] < num[j-1]:
                num[j], num[j-1] = num[j-1], num[j]
            else:
                break

总结:把待排序的数据划分成几个子序列,然后再根据某种关系映射,再待排序的数据放入子序列中,然后再根据某种排序方法将子序列的数据进行排序,最后将子序列的数据合并就可以得到排序后的序列,而且排序数据尽量服从均匀分布,可提高桶排序的效率

基数排序

思路:

  • 取得数组中的最大数,并取得位数;
  • 从最低位开始取每个位的数据,组成基数数组;
  • 将基数组数据填充到原数组;
  • 反复第2,3步, 第2部每轮向前取一位数,反复取到最高位结束

代码:

# 基数排序 未实现排负数
def radis_sort(num: list[int]) -> None:
    #获取最多需要被排序几次
    times = len(str(max(num)))
    for i in range(times):
        #分配
        bucket=[[] for _ in range(10)]
        for j in num:
            weishu = j // (10**i) % 10  # 从个位开始取数据
            bucket[weishu].append(j)
        #收集
        num.clear()
        for i in range(10):
            num += bucket[i]

总结:就是将数据根据相同位数排序好,最后形成一个排序完成的序列,不过这个写法无法排序负数,望有朋友能够提供改进思路

堆排序

思路:

  • 建堆(明白堆是什么)
  • 找到堆中最大的元素(从小到大排序)
  • 移出最大的元素
  • 将最后一个元素赋值给顶元素
  • 移走完堆顶元素后,再维护堆结构即可
  • 反复2到最后过程

代码:

# 堆排序
def down(heap:list[int], index:int, size:int):
    '''
    维护堆的特性
    '''
    # 建立一个变量,来存储最大值的索引
    max_index = index
    # 获取左节点的索引
    left = max_index * 2 + 1  
    # 获取右节点的索引
    right = max_index * 2 + 2
    # 进行比较获取出最大值索引来
    if left < size and heap[max_index] < heap[left]:
        max_index = left
    if right < size and heap[max_index] < heap[right]:
        max_index = right
    # 如果max_index 和 index 值不一样,说明需要进行交换
    if max_index != index:
        heap[max_index], heap[index] = heap[index], heap[max_index]
        down(heap, max_index, size)


def heap_sort(heap: list[int]):
    # 获取堆有多少数据
    size = len(heap)
    # 打印原始数据
    # print(heap)
    # 建堆
    for i in range(size//2, -1, -1): # 为了保证一次性取到最大值,所以让索引倒取
        down(heap, i, size)
    # 打印维护后数据
    # print(heap)
    # 排序
    for i in range(size-1,0,-1):
        # 将最大值和未排序的最一个索引进行交换
        heap[i],heap[0] = heap[0],heap[i]
        # 维护堆的特性
        down(heap, 0, i)
    # 打印排序好的数据
    # print(heap)

总结:就是要明白什么是堆,堆又可分为最小堆和最大堆,最后只要不断的根节点取出,在维护好堆的特性就可得到一个排序好的序列,不明白什么是堆可以参考一分钟带你读懂什么是堆? - 知乎 (zhihu.com)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值