希尔排序详解
希尔排序(Shell Sort)是插入排序的高效改进版本,通过将原始列表分割成多个子序列进行局部排序,逐步减少子序列长度,最终实现整体有序。其核心思想是通过增量序列实现数据元素的预排序。
核心原理
-
增量序列选择
选取递减的增量序列 gap1>gap2>...>gapk=1gap_1 > gap_2 > ... > gap_k = 1gap1>gap2>...>gapk=1,常用序列:- 希尔原始序列:gap=n2,n4,...,1gap = \frac{n}{2}, \frac{n}{4}, ..., 1gap=2n,4n,...,1
- Knuth序列:gap=3k−12gap = \frac{3^k-1}{2}gap=23k−1(如1,4,13,40…)
-
分组插入排序
对每个增量 gapgapgap:- 将列表分为 gapgapgap 个子序列
- 每个子序列由相隔 gapgapgap 的元素组成
- 对每个子序列执行插入排序
-
增量递减
当 gap=1gap=1gap=1 时,退化为标准插入排序,此时列表已基本有序,排序效率极高。
时间复杂度分析
{O(n2)最坏情况O(n1.5)平均情况(希尔序列)O(nlog2n)最优情况(Knuth序列)
\begin{cases}
O(n^2) & \text{最坏情况} \\
O(n^{1.5}) & \text{平均情况(希尔序列)} \\
O(n\log^2 n) & \text{最优情况(Knuth序列)}
\end{cases}
⎩⎨⎧O(n2)O(n1.5)O(nlog2n)最坏情况平均情况(希尔序列)最优情况(Knuth序列)
空间复杂度:O(1)O(1)O(1)(原地排序)
算法特性
- 不稳定排序:相同元素可能跨越交换位置
- 适应性:对部分有序数据效率显著提升
- 增量敏感性:性能取决于增量序列选择
Python实现
def shell_sort(arr):
n = len(arr)
gap = n // 2 # 初始增量
while gap > 0:
# 对每个子序列执行插入排序
for i in range(gap, n):
temp = arr[i]
j = i
# 在子序列内向前比较
while j >= gap and arr[j - gap] > temp:
arr[j] = arr[j - gap]
j -= gap
arr[j] = temp
gap //= 2 # 增量减半
return arr
# 示例
data = [9, 7, 6, 15, 17, 5, 10, 11]
print(shell_sort(data)) # 输出:[5, 6, 7, 9, 10, 11, 15, 17]
执行过程示例(增量序列:4→2→1)
初始数据:[9, 7, 6, 15, 17, 5, 10, 11]
-
gap=4
- 子序列1:
[9, 17]→ 排序后[9, 17] - 子序列2:
[7, 5]→ 排序后[5, 7] - 子序列3:
[6, 10]→ 排序后[6, 10] - 子序列4:
[15, 11]→ 排序后[11, 15] - 结果:
[9, 5, 6, 11, 17, 7, 10, 15]
- 子序列1:
-
gap=2
- 子序列1:
[9, 6, 17, 10]→ 排序后[6, 9, 10, 17] - 子序列2:
[5, 11, 7, 15]→ 排序后[5, 7, 11, 15] - 结果:
[6, 5, 9, 7, 10, 11, 17, 15]
- 子序列1:
-
gap=1
- 标准插入排序,最终结果:
[5, 6, 7, 9, 10, 11, 15, 17]
- 标准插入排序,最终结果:
应用场景
- 中等规模数据集(n<104n < 10^4n<104)
- 内存受限环境(原地排序)
- 嵌入式系统开发
- 快速排序的辅助子过程

3603

被折叠的 条评论
为什么被折叠?



