希尔排序算法详解:原理、实现与优化
一、算法概述
希尔排序(Shell Sort)是 Donald Shell 于 1959 年提出的一种改进的插入排序算法,也被称为缩小增量排序。它的核心在于将原始数组分解为若干个子序列进行插入排序,随着增量逐渐减小,最终对整个数组进行一次标准的插入排序。
基本特性
- 时间复杂度:取决于增量序列的选择,通常在 O(n^1.3) 到 O(n^2) 之间
- 空间复杂度:O(1),属于原地排序
- 稳定性:不稳定排序算法
- 适用场景:中等规模数据,特别是部分有序的数据集
二、算法原理详解
核心思想
- 分组插入排序:按照当前的增量 gap 将数组分为若干子序列
- 逐步缩小增量:每次迭代缩小 gap 值,直到 gap 变为 1
- 最终插入排序:当 gap=1 时,执行标准的插入排序完成收尾
增量序列选择
不同的增量序列直接影响性能表现,常用的有:
- Shell 原始序列:gap = n/2, n/4, …, 1
- Hibbard 序列:1, 3, 7, …, 2^k - 1
- Sedgewick 序列:1, 5, 19, 41, 109, …
三、执行过程演示
以数组 [8, 9, 1, 7, 2, 3, 5, 4, 6, 0] 为例,采用 Shell 原始增量序列(gap 从 5 开始):
初始状态
[8, 9, 1, 7, 2, 3, 5, 4, 6, 0]
第一轮:gap = 5
将数组分为 5 组进行组内排序:
- (8, 3), (9, 5), (1, 4), (7, 6), (2, 0)
排序后结果:
[3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
第二轮:gap = 2
将数组分为 2 组:
- (3, 1, 0, 9, 7), (5, 6, 8, 4, 2)
排序后结果:
[0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
第三轮:gap = 1
此时为标准插入排序,将剩余无序元素归位:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
四、Java 实现
下面是一个完整的 Java 实现示例,使用了基础的 Shell 原始增量序列。代码中包含了必要的注释,方便理解每一步的逻辑。
package com.kwan.springbootkwan.controller;
public class {
{
(arr == || arr.length <= ) {
;
}
arr.length;
( n / ; gap > ; gap /= ) {
( gap; i < n; i++) {
arr[i];
j;
(j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
{
[] arr = {, , , , , , , , , };
System.out.println();
printArray(arr);
System.out.println();
shellSort(arr);
printArray(arr);
}
{
( num : arr) {
System.out.print(num + );
}
System.out.println();
}
}


