Python 算法(二)补充,排序算法稳定性,工程中综合排序,比较器,桶排序

本文深入解析排序算法的稳定性概念,对比分析冒泡、插入、归并等稳定排序算法与选择、快排、堆排等不稳定排序算法的特点。探讨工程实践中不同场景下排序算法的选择策略,如快排适用于大样本量的基础类型排序,而归并排序则适合大样本量的对象字段排序,插入排序适合小规模数据。同时,文章介绍了比较器在Python中的应用,以及桶排序、计数排序、基数排序等非比较型排序算法的时间和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、排序算法稳定性及其汇总

定义:排序过程保证相同元素次序不发生改变。

意义:业务需求,三个属性(name, age, height)的时候, height排序的时候,原始顺序age不会发送改变(按照height和age排序)。

稳定性排序:

  • 冒泡排序、插入排序、归并排序

不稳定性排序:

  • 选择排序:[4,4,4,3],第1个4和3交换位置,发送变化
  • 快排:[4,4,4,5], 随机选择的4跟5交换发生变化(“01 stable sort”可以保证稳定性,很难)
  • 堆排: [4,4,4,5], 实现大根堆过程, 第二四元素交换位置,发送变化

2、工程上综合排序(综合使用多种排序)

  • 快排:样本量大,类型为基础类型,int、double、float等
  • 归并:样本量大、类型为class、按照对象某个字段排序,常和插排一起使用
  • 插入:样本量很短,长度模式小于60左右,常数项很低

3、比较器

定义:快速实现排序等操作。


4、桶排序、计数排序、基数排序

桶排序定义: 计数排序的升级版,将数组分到有限数量的桶里。每个桶再个别排序

  • 1,非基于比较的排序,与被排序的样本的实际数据状况很有关系,所以实际中并不经常使用
  • 2,时间复杂度O(N),额外空间复杂度O(N)
  • 3,稳定的排序

题目

给定一个数组, 求如果排序之后, 相邻的最大差值, 要求时间复杂度O(N), 且要求不能用非基于比较的排序。

思路:

  1. 创建N+1个桶,创建一个对象三个属性has, max_v, min_v,判断第一个和最后一个数是否相等,相等直接结束
  2. 1号桶放最小值,N+1号桶放最大值,然后将数组中值依次放入对应桶
  3. 最后肯定存在一个空桶,用来保证桶内不会存在最大值(过滤掉桶中变量的比较)
  4. 比较相邻桶的差值,就可以找出最大值
def max_gap(nums):
    if nums is None or len(nums)<2:
        return 0
    nums_len = len(nums)
    nums_min = min(nums)
    nums_max = max(nums)
    if nums_min == nums_max:
        return 0

    # 将数据依次入桶
    has_list = [False for _ in range(nums_len+1)]
    max_list = [i for i in range(nums_len+1)]
    min_list = [i for i in range(nums_len+1)]
    for i in range(nums_len):
        bid = int((i - nums_min)*nums_len / nums_max-nums_min)
        max_list[bid] = max(max_list[bid], nums[i]) if has_list[bid] else nums[i]
        min_list[bid] = min(min_list[bid], nums[i]) if has_list[bid] else nums[i]
        has_list[bid] = True

    # 比较桶之间的最大值
    res = 0
    last_max = max_list[0]
    for i in range(1, nums_len):
        if has_list[i]:
            res = max(res, min_list[i]-last_max)
            last_max = max_list[i]
    return res
print(max_gap([0,5,8,10,14,30,31]))
# 疑惑,这种不也是O(N)的复杂度吗?
def bucket_sort(arr):
    max_v = 0
    for i in range(len(arr)-1):
        border_dif = abs(arr[i] - arr[i+1])
        if border_dif > max_v:
            max_v = border_dif
    return max_v 

bucket_sort([1,4,9,20,21])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值