数据结构基础(12)------------Shell排序
1.Shell排序是DL. Shell于1959年针对直接插入排序算法改进提出的,属于插入排序的范畴,是对直接插入排序算法的改进。直接插入排序在基本有序时效率较高,并且在序列规模不是很大时效率也很高,Shell排序就是针对这两点进行改进。核心思想是:待排序列有n个元素,先取一个小于n的整数h1作为第一个增量,把待排序列以间隔h1分成若干子序列,子序列内使用插入排序;然后取第二个增量h2(< h1),重复上述的划分和排序,直至所取的增量hl = 1 (h1 > h2 > ... > hl)。(缩小增量排序)
这样不管序列多么庞大,在先前较大步长分组下每个子序列规模都不是很大,用直接插入效率很高;后面步长变小,子序列变大,但由于整体有序性越来越明显,排序效率依然很高,大大提高了时间效率。
依靠这个特别的实现机制,希尔排序对于多达几千个数据项的,中等大小规模的数组排序表现良好。希尔排序不像快速排序和其它时间复杂度为O(N*logN)的排序算法那么快,因此对非常大的文件排序,它不是最优选择。但是,希尔排序比选择排序和插入排序这种时间复杂度为O(N2)的排序算法还是要快得多,并且它非常容易实现。它在最坏情况下的执行效率和在平均情况下的执行效率相比没有差很多。
由于Shell排序算法是按增量分组进行的排序,所以Shell排序算法是一种不稳定的排序算法。
希尔排序通过在排序的开始阶段对相距较远的元素进行比较和交换,迅速地消除了大量的无序,使得后面的交换工作量减少。理论分析证明,在表中元素较多的情况下,希尔排序要比交换排序快的多,其排序所用的时间和表长的 1.5 次方成正比。
2.算法的测试用例:功能性测试:输入一个乱序的整型数组;特殊值输入,输入一个空指针和长度为零的整形数组
3.代码示例:(VS中编译通过,并测试)
void shell_sort(int *a,int length) //代码修改于《大话数据结构》P392
{
if (nullptr==a || length==0) //对输入进行检测
{
return ;
}
int increment=length-1; //最大增量
do
{
increment=increment/3+1; //调整增量大小,不断减小,子序列不断增大。
for (int i=increment;i<length;++i)
{
int key=a[i];
if (a[i-increment]>a[i]) //判断是否需要插入
{
int j=i-increment;
for (;j>=0 && a[j]>key;j=j-increment)//记录后移
{
a[j+increment]=a[j];
}
a[j+increment]=key; //插入记录
}
}
}
while (increment>1);
}