写在前面
初学数据结构这门课程时,希尔排序是我不能理解的一种算法。现在重新回顾一下,自己尝试写一写希尔排序算法的代码,突然觉得茅塞顿开,所以在这里写一篇博客记录一下。
希尔排序基本思想
基本思想:
对待排记录序列先“宏观”调整,再“微观”调整。先将待排序记录序列分割成若干个“较稀疏的”子序列,分别进行直接插入排序。经过上述粗略调整,整个序列中的记录已经基本有序,最后对全部记录进行一次直接插入排序。
希尔排序算法实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int MAXSIZE = 100;
void shell_sort(int *data, int len);
int main()
{
int data[MAXSIZE];
time_t t;
srand((unsigned)time(&t));
// 随机生成20个数
for(int i=0;i<20;i++)
{
data[i] = rand() % 100;
}
for(int i=0;i<20;i++)
{
printf("%d ", data[i]);
}
printf("\n");
shell_sort(data, 20);
for(int i=0;i<20;i++)
{
printf("%d ", data[i]);
}
printf("\n");
return 0;
}
// 希尔排序
void shell_sort(int *data, int len)
{
int tmp; // 临时变量,作用相当于哨兵
int gap = len / 2; // 增量gap,初始值为数组长度的一半
while(gap > 0)
{
for (int i = 0 + gap; i < len; i++)
{
if (data[i] < data[i - gap])
{
int j = i - gap;
tmp = data[i];
// 循环变量j要大于等于数组第一个元素的下标
// 循环是为哨兵找插入的位置,所以是data[j] > tmp
while(j >= 0 && data[j] > tmp)
{
data[j + gap] = data[j];
j -= gap;
}
data[j + gap] = tmp;
}
}
gap /= 2; // 增量记得变化,否则死循环了
}
}
希尔排序算法的分析比较困难,我自己也没有看懂,我看到的希尔排序算法平均时间复杂度为
O
(
n
1.3
)
O(n^{1.3})
O(n1.3),最坏时间复杂度和特殊情况不考虑。
因为希尔排序的最后一次排序就是直接插入排序,而插入排序在序列基本有序的时候时间复杂度可以提高为
O
(
n
)
O(n)
O(n),所以希尔排序的前几次排序都是在尽量做到序列基本有序。但是到目前为止,尚未有人求得一种最好的增量序列,但大量研究也得出了一些局部的结论。
文中都是我个人的理解,如有错误的地方欢迎下方评论告诉我,我及时更正,大家共同进步