前言
希尔排序(Shell Sort)是一种改进的插入排序算法,它通过将数组分成多个子序列进行排序,逐步减小子序列的长度,最终完成整个数组的排序。希尔排序的核心思想是通过排序较远距离的元素来使数组局部有序,从而减少后续插入排序的工作量。
虽然使用了三重循环,但由于希尔排序的特殊设计,其速度处于佼佼者的地位,不过并不稳定,指相等数字的前后关系变化。
步骤
- 选择一个增量序列,通常是使用 Knuth 提出的增量序列(3^k - 1)/ 2 其中 k 为递减的整数序列(或增量为数组长度累次除以2) 。
- 对于每个增量,从增量开始,将数组划分为多个较小的子序列。
- 对每个子序列进行插入排序。即,对于子序列中的每个元素,与同一子序列中对应位置的前一个元素进行比较,如果需要,则交换它们的位置。
- 不断缩小增量,重复步骤 2 和 3,直到增量为 1。
- 最后再进行一次完整的插入排序,此时数组已经基本有序,插入排序的工作量会大大减少。
举例子
将[1,5,3,8,9,6,5,10,12]变为增序
代码
C语言
cs
#include <stdio.h>
void shellSort(int arr[], int n) {
int gap, i, j, temp;
// 选择初始增量
for (gap = n / 2; gap > 0; gap /= 2) {
for (i = gap; i < n; i++) {
temp = arr[i];
// 对子序列进行插入排序
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
// 示例
int main() {
int arr[] = {9, 5, 1, 8, 3, 7, 4, 6, 2};
int n = sizeof(arr) / sizeof(arr[0]);
shellSort(arr, n);
printf("排序后的数组:");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
Python
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 # 缩小增量
# 示例
my_list = [9, 5, 1, 8, 3, 7, 4, 6, 2]
shell_sort(my_list)
print(my_list)
# 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
总结
相对于传统的插入排序,希尔排序通过提前部分排序,可以有效地减少比较和交换的次数,从而提高算法的效率。希尔排序的时间复杂度取决于增量序列的选择,但通常情况下介于 O(n) 和 O(n^2) 之间。
需要注意的是,希尔排序是一种不稳定的排序算法,即相等元素的相对顺序有可能在排序过程中发生改变。
总体而言,希尔排序在实践中具有较高的性能表现,尤其适用于中等大小的数组排序。