希尔排序(Shell Sort)是一种基于插入排序的高效排序算法,其核心思想是通过引入“增量”来改进直接插入排序在处理大规模无序数据时效率低下的问题
2026/8/4 9:29:17 网站建设 项目流程

希尔排序(Shell Sort)是一种基于插入排序的高效排序算法,其核心思想是通过引入“增量”来改进直接插入排序在处理大规模无序数据时效率低下的问题。它由Donald Shell于1959年提出,因此得名。

基本概念与原理:

  • 别名:缩小增量排序。
  • 核心思想
    1. 将待排序序列按照某个“增量”k分为若干个子序列,每个子序列由相隔k个位置的元素组成;
    2. 对每个子序列进行直接插入排序
    3. 随着排序的进行,逐步减小增量k(如每次折半),重复上述分组和排序;
    4. 当增量减至1时,对整个序列进行最后一次直接插入排序,此时序列已基本有序,因此效率较高。

该方法的优势在于:早期的大步长移动使得远距离元素能快速接近目标位置,显著减少总的比较和移动次数。


示例过程详解(增量序列:5, 3, 1)

原始数组:[48, 37, 64, 96, 75, 12, 26, 48, 54, 03]

  • 第一趟(增量 = 5)

    • 分组:(48,12), (37,26), (64,48), (96,54), (75,03)
    • 各组内排序后得到:[12, 26, 48, 54, 03, 48, 37, 64, 96, 75]
  • 第二趟(增量 = 3)

    • 分组:(12,54,37,75), (26,48,64), (48,96)
    • 插入排序各组后结果为:[12, 03, 48, 37, 26, 48, 54, 64, 96, 75]
  • 第三趟(增量 = 1)

    • 整体做一次直接插入排序
    • 最终结果:[03, 12, 26, 37, 48, 48, 54, 64, 75, 96]

特点总结:

  • 时间复杂度
    • 依赖于所选的增量序列。
    • 使用原始希尔增量(n/2, n/4, …, 1)时,最坏情况为 O(n²),平均约为 O(n^1.3)。
    • 若使用更优增量序列(如Hibbard、Sedgewick等),可提升到接近 O(n log n)。
  • 空间复杂度:O(1),仅需常数额外空间用于交换。
  • 稳定性不稳定,因为在不同增量下的插入排序可能导致相同元素相对位置改变。

代码实现参考(完整版):

defshell_sort(arr):n=len(arr)gap=n//2# 初始增量whilegap>0:foriinrange(gap,n):temp=arr[i]j=i# 在同一增量组内进行插入排序whilej>=gapandarr[j-gap]>temp:arr[j]=arr[j-gap]j-=gap arr[j]=temp gap//=2# 缩小增量# 示例使用data=[48,37,64,96,75,12,26,48,54,3]shell_sort(data)print(data)# 输出: [3, 12, 26, 37, 48, 48, 54, 64, 75, 96]

希尔排序的性能在很大程度上依赖于所采用的增量序列(gap sequence)。不同的增量序列会显著影响算法的时间复杂度和实际运行效率。以下是几种常见的增量序列及其对性能的影响:


1.原始希尔增量(Shell’s Original Sequence)

  • 公式:$ \text{gap} = \left\lfloor \frac{n}{2} \right\rfloor, \left\lfloor \frac{n}{4} \right\rfloor, \dots, 1 $
  • 即每次将增量折半:n//2, n//4, ..., 1
  • 时间复杂度
    • 最坏情况:$ O(n^2) $
    • 平均情况:约 $ O(n^{1.5}) $
  • 特点
    • 简单易实现,是最早提出的增量方式。
    • 但由于相邻增量可能有公因数,导致部分元素分组重复,无法充分预排序。

2.Hibbard 增量序列(Hibbard’s Sequence)

  • 公式:$ 2^k - 1 $,即1, 3, 7, 15, 31, ...
  • 取小于 n 的最大值开始递减
  • 时间复杂度:最坏 $ O(n^{3/2}) $
  • 优点
    • 每个增量与下一个无公因数,能更好地打乱数据分布;
    • 分组更均匀,有助于提高排序效率。

3.Sedgewick 增量序列(Sedgewick’s Sequence)

  • 形式较复杂,典型构造为:
    • $ \text{gap}_i =
      \begin{cases}
      9 \times 2^i - 9 \times 2^{i/2} + 1 & \text{if } i \text{ even} \
      8 \times 2^i - 6 \times 2^{(i+1)/2} + 1 & \text{if } i \text{ odd}
      \end{cases} $
    • 实际常用前几项:1, 5, 19, 41, 109, ...
  • 时间复杂度:最坏可达 $ O(n^{4/3}) $,平均接近 $ O(n \log n) $
  • 优点:目前实践中表现最好的之一,适合大规模数据。

4.Knuth 增量序列(Knuth’s Sequence)

  • 公式:$ \frac{3^k - 1}{2} $,即1, 4, 13, 40, 121, ...
  • 时间复杂度:最坏 $ O(n^{3/2}) $
  • 优点
    • 增长适中,避免过快收敛到1;
    • 在小到中等规模数据上表现稳定。

不同增量序列的性能对比(大致)

增量序列最坏时间复杂度平均性能实现难度推荐程度
原始希尔$ O(n^2) $一般简单⭐⭐☆☆☆
Hibbard$ O(n^{3/2}) $较好中等⭐⭐⭐☆☆
Knuth$ O(n^{3/2}) $稳定中等⭐⭐⭐⭐☆
Sedgewick$ O(n^{4/3}) $优秀较难⭐⭐⭐⭐⭐

总结:

选择合适的增量序列可以大幅提升希尔排序的效率。虽然所有版本都是基于“缩小增量”的思想,但好的增量序列能够:

  • 减少比较和移动次数;
  • 提高子序列的有序性;
  • 加速最终插入排序阶段的完成。

推荐实践:对于一般用途,使用Knuth 序列Sedgewick 序列能获得更优性能;教学或简单场景可用原始希尔增量。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询