数据结构与算法——14. 希尔排序

希尔排序(Shell Sort)

我们注意到:在插入排序中,列表越接近有序,比对次数就越少。从这个情况入手,希尔排序以插入排序作为基础,对无序表进行**“等间隔”划分子列表**,每个子列表都执行插入排序

比如,间隔为3进行分组,如下图,每行深色的为一组:

在这里插入图片描述

间隔为多少,那么子列表就有多少个。随着间隔的缩小,子列表的数量越来越少,无序表的整体越来越接近有序,从而减少整体排序的比对次数

对3个子列表分别进行插入排序后,整个表的状态(最下面一行):

在这里插入图片描述

最后一趟是标准的插入排序,但由于前面几趟已经将列表处理到接近有序,这一趟仅需少数几次移动即可完成。

python代码实现

子列表的间隔一般从n/2开始,每趟倍增:n/4, n/8……直到1。

def shell_sort(a_list):
    # 初始化间隔大小
    sublist_count = len(a_list) // 2
    # 只要间隔大于0,就对子列表进行排序
    while sublist_count > 0:
        for start_position in range(sublist_count):
            gap_insertion_sort(a_list, start_position, sublist_count)
        # 缩小间隔
        sublist_count = sublist_count // 2


def gap_insertion_sort(a_list, start, gap):
    """
    带间隔的插入排序
    :param a_list: 需要排序的列表
    :param start: 偏移量
    :param gap: 间隔的大小
    """
    # 从每个子列表的第start个元素开始,进行带间隔的插入排序
    for i in range(start + gap, len(a_list), gap):
        current_value = a_list[i]
        position = i
        # 当同一组中有逆序的数据项时,按照间隔移动数据项,腾出空位
        while position >= gap and a_list[position - gap] > current_value:
            a_list[position] = a_list[position - gap]
            # 空位的位置向前移gap位
            position = position - gap
        # 将当前数据项放入空位
        a_list[position] = current_value

算法分析

粗看上去,希尔排序以插入排序为基础,可能并不会比插入排序好。但由于每趟都使得列表更加接近有序,这过程会减少很多原先需要的“无效”比对

希尔排序的详尽分析比较复杂,大致说是介于 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2)之间。如果将间隔保持在 2 k − 1 2^k-1 2k1(1、3、5、7、15、31等等),希尔排序的时间复杂度约为 O ( n 3 2 ) O(n^{ \frac {3}{2}}) O(n23)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花_城

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值