[排序算法]希尔排序

前言

希尔排序是对直接插入排序的优化,其思路是先创造"基本有序"的条件,再进行精细的插入排序

如果你还没有学会直接插入排序算法,那请先看博主前一篇文章:[排序算法]直接插入排序

学完直接插入排序,我们不难得出其优缺点:

  1. 优点 :当待排序序列基本有序 时,直接插入排序的效率非常高,近似 O(n)

  2. 缺点 :当待排序序列完全逆序 时,效率极低,为 O(n²)。因为每次插入一个新元素,都需要与前面所有已排序的元素进行比较和移动。

我们希尔排序就是为了降低缺点的影响,通过预处理,使待排序序列"基本有序"。

基本思想

希尔排序是对直接插入排序的优化,其核心思想是通过一个递减的步长序列(gap sequence)将数组分成若干子序列,对每个子序列进行插入排序,使数组逐渐"基本有序",最后当步长为1时进行直接插入排序。这种预处理能有效减少直接插入排序中的比较和移动次数,从而提升整体效率。
有点懵?先不要慌!下面咱们逐步分析。

具体步骤:

  1. 选择一个初始步长gap(通常为n/2或n/3)。

  2. 将数组中间隔为gap的元素分在同一组,形成多个子序列。

  3. 对每个子序列进行插入排序。

  4. 缩小gap(例如,使用gap = gap / 3 + 1),重复步骤2-3,直到gap=1。

  5. 当gap=1时,执行一次直接插入排序,此时数组已基本有序,排序效率很高。

打个比方:

详解代码

cpp 复制代码
//希尔排序
void ShellSort(int* a, int n)
{
    //gap是步长,gap的值就是每组数据间隔
    //比如第一组第一个数据为arr[i]那下一个即为arr[i+gap]
    int gap = n;
    while (gap > 1)
    {
        //推荐写法:除3
        gap = gap / 3 + 1;
        //i如果大于等于n-gap,会导致a[end+gap]越界访问
        for (int i = 0; i < n - gap; i++)
        {
            //从第一个元素开始
            //end含义为已排序部分的最后一个元素的下标
            int end = i;
            //tmp为该组下一个元素的值
            int tmp = a[end + gap];
            //end如果小于0,则证明a[end+gap]已经和该组第一个元素互换了值
            while (end >= 0)
            {
                //同一组中,若前面的数大于后面的
                if (a[end] > tmp)
                {
                    //后面的值等于前面的
                    a[end + gap] = a[end];
                    //end自身减gap
                    end -= gap;
                }
                //否则证明已经有序
                else
                {
                    break;
                }
            }
            //两种情况,if满足一种,不满足一种
            a[end + gap] = tmp;
        }
    }
}

希尔排序的时间复杂度范围大致在 O(n log²n) 到 O(n²) 之间。通过选择优秀的增量序列,其平均时间复杂度可以优化到大约 O(n^1.3) 到 O(n^1.5),这明显优于 O(n²) 的直接插入排序。
希尔排序时间复杂度不好计算,因为 gap 的取值很多,导致很难去计算,因此很多书中给出的希尔排序的时间复杂度都不固定。《数据结构(C语言版)》--- 严蔚敏书中给出的时间复杂度为:


-------有问题欢迎私信和评论------

相关推荐
FakeOccupational4 小时前
【数学 密码学】量子通信:光的偏振&极化的量子不确定性特性 + 量子密钥分发 BB84算法步骤
算法·密码学
ZhengEnCi6 小时前
S10-蓝桥杯 17822 乐乐的积木塔
算法
贾斯汀玛尔斯6 小时前
每天学一个算法--拓扑排序(Topological Sort)
算法·深度优先
大龄程序员狗哥6 小时前
第25篇:Q-Learning算法解析——强化学习中的经典“价值”学习(原理解析)
人工智能·学习·算法
exp_add36 小时前
质数相关知识
算法
小辉同志7 小时前
215. 数组中的第K个最大元素
数据结构·算法·leetcode··快速选择
小O的算法实验室7 小时前
2025年IEEE TITS,基于矩阵的进化计算+面向无线传感器网络数据收集无人机路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
OidEncoder7 小时前
编码器分辨率与机械精度的关系
人工智能·算法·机器人·自动化
memcpy07 小时前
LeetCode 2615. 等值距离和【相同元素分组+前缀和;考虑距离和的增量】中等
算法·leetcode·职场和发展
炽烈小老头8 小时前
【 每天学习一点算法 2026/04/22】四数相加 II
学习·算法