数据结构C语言版希尔排序
文章目录
希尔排序
希尔排序的提出是对直接掺入排序的进一步优化,直接插入排序插入排序在对几乎已经排好序的数据操作时,效率高,即可达到线性排序的效率但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位,所以在1959年D.L.Shell正式提出了shell算法,我觉得这给当时的人指明了一个方向,开辟了灵感的源泉,因为shell排序是第一个突破了O(n^2 ) 时间复杂度的排序算法,因为在1959年之前的相当长的一段时间里,各种各样的排序算法无论是怎么设计,都始终无法突破O(n^2), 在当时直接插入排序已经是相当优秀的了,而排序算法不可能突破O(n^2)的声音成为了当时的主流.所以可以想象为了破除这个魔咒,他付出了多少努力,所以能够成为牛顿所站的巨人的肩膀我想也是一件幸事。
1.基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
2.示例:
3.希尔排序的特点:希尔排序的子序列的构成是讲相隔某个“增量”的记录组成一个子序列,然后关键字是和同一个子序列中的前一个纪录的关键字进行比较,所以关键字较小的记录就是跳跃式的移动,那么最后一趟增量为1的插入排序时,序列已经基本有序,只需要做少量的操作即可。
4.希尔排序的分析是一个复杂的问题,它的时间是增量的函数,而这涉及到一些数学上胃解决的难题,因此现在并没有一种最好的增量序列。增量序列有多种取法,但是必须遵循增量序列中的值没有除1之外的公因子,并且最后一个增量值必须等于1.
5.代码(在数据结构C语言版插入排序的基础上写入):
//基础:插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
//通过分组使数组渐变有序
//最后在直接插入排序
void ShellSort(int *d, int length)//希尔排序
{
assert(d);
int i = 0, j = 0;
int gap = 0;//步长即分组的个数
int temp = 0;//哨兵
for (gap = length / 2; gap > 0; gap /= 2)//完成分组
{
for (i = gap; i < length; i++)//寻找分组后的元素
{
temp = d[i];//哨兵位
for (j = i - gap; j >= 0 && temp < d[j]; j -= gap)//根据下一个分组的下标寻找上个分组的元素
{
d[j + gap] = d[j];
}
d[j + gap] = temp;//填补上一个分组的相应位置元素
}
}
printf("排序成功!\n\n");
}