数据结构之几种常见的排序算法(二)——希尔、计数、桶排、基数

本文深入解析希尔排序、计数排序、桶排序及基数排序的原理与实现,通过具体代码示例,阐述各种排序算法的时间与空间复杂度,适用于数据结构与算法初学者。

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

1. 希尔排序

  • 希尔排序是一种分组插入排序算法
  • 首先取一个整数d1=n/2,将元素分为d1个组,每组相邻两元素之间的距离为d1,在各组内进行直接插入排序;
  • 取第二个整数d2=d1/2,重复上述分组排序过程,直到di=1,即所有元素在同一组内进行直接插入排序。
  • 希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序;最后一趟排序使得所有数据有序。

重点代码:

#  修改插入排序间隙
def insert_sort_gap(li, d): # d=1为正常插入排序 
    for i in range(d, len(li)):
        tmp = li[i]
        j = i - d
        while j >= 0 and li[j] > tmp:
            li[j + d] = li[j]
            j -= d
        li[j + d] = tmp

# 希尔排序
def shell_sort(li):
    d = len(li) // 2
    while d > 0:
        insert_sort_gap(li, d)
        d = d // 2

希尔排序的时间复杂度讨论比较复杂,并且和选取的gap序列有关。

2. 计数排序

现在有一个列表,已知列表中数的范围都在0到100之间。 设计算法在o(n)时间复杂度内将列表进行排序。

def count_sort(li,max_num=100):
    count=[0]*(max_num+1)
    for v in li:
        count[v]+=1
    li.clear()
    for i,v in enumerate(count): # 表示i这个数出现了v次
        for j in range(v):
            li.append(i)

时间复杂度o(n)。不适合包含数过大的情况

3. 桶排序

  • 在计数排序中,如果元素的范围比较大(比如1到1亿之间),如何改造算法?
  • 桶排序(Bucket Sort):首先将元素分在不同的桶之中,再对每个桶中的元素排序。
    在这里插入图片描述
  • 桶排序的表现取决于数据的分布(适合平均分布)。也就是需要对不同数据排序时采取不同发分桶策略。
  • 平均情况时间复杂度:o(n+k)
  • 最坏情况时间复杂度:o(n2k)
  • 空间复杂度:o(nk)

代码略

4. 基数排序

  • 多关键字排序:假如现在有一个员工表,要求按照薪资排序,薪资相同的员工按照年龄排序
  • 先按照年龄进行排序,再按照薪资进行稳定的排序

  • 对32,13,94,52,17,54,93排序,是否可以看做多关键字排序?
  • 正常应该是按照先十位数进行排序,十位数相等再按照个位数进行稳定的排序
  • 若基数排序,则先比较个位数,再比较十位数

重点代码:

# i=0 个位;1 十位;2 百位...
def get_digit(num, i):
    return num // (10 ** i) % 10

def radix_sort(li):
    max_num = max(li)
    i = 0
    while 10 ** i <= max_num:
        buckets = [[] for v in range(10)]
        for val in li:
            digit = get_digit(val, i)
            buckets[digit].append(val)
        li.clear()
        for bucket in buckets:
            for val in bucket:
                li.append(val)
        i += 1

时间复杂度:o(kn)、空间复杂度:o(k+n),其中k表示数字位数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值