1.希尔排序简介
希尔排序,是插入排序的一种进阶算法,通过一个不断缩小的增量序列,对无序序列反复的进行拆分后的序列使用插入排序的一种算法,所以也叫做“缩小增量排序”或者“递减增量排序”。
既然希尔排序也是使用插入排序进行序列排序操作,为什么会有希尔排序呢?
这是基于插入排序的两点性质而来:
第一:对一个“几乎”已经排好序的无序序列,插入排序的效率是很高的,可以达到线性排序的效率。比如,当序列中只有一位元素没有在适当的位置,那么整个序列只需要移动该序列的位置即可达到完成排序的任务。
第二:但是一般的无序序列不是一个“几乎”已经排好序的序列,所以插入排序是低效的。因为它每次只能移动一位元素。
基于以上两点出现了希尔排序,那么希尔排序到底如何利用了这两个性质的?
基本思想:
(1):把待排序列,分为多个间隔为h的子序列,然后对每个子序列进行直接插入排序;
(2):重复(1)多次,每次间隔h不同,并且越来越小;
(3):最后一次选取,间隔h=1,完成排序!
2.排序过程
比如有一个无需数列如下所示:
8 | 3 | 9 | 11 | 2 | 1 | 4 | 7 | 5 | 10 | 6 |
现在我们选择三个间隔的子序列,分别排序,比如就选5、3、1;
(1)当h=5时,我们依次化为三个子序列。
8 | 3 | 9 | 11 | 2 | 1 | 4 | 7 | 5 | 10 | 6 |
然后依次进行比较:比如8、1、6进行比较然后依次从小到大换位置为1、6、8;然后顺位比较3、4,因为就是3<4,所以位置不用动;再比较9、7,然后互换位置;再比较11和5,互换位置;最后比较2和10不用换位置,如此下来,得到一个新的无序数列。
1 | 3 | 7 | 5 | 2 | 6 | 4 | 9 | 11 | 10 | 8 |
(2)当h=3时,我们依次化为四个子序列。
1 | 3 | 7 | 5 | 2 | 6 | 4 | 9 | 11 | 10 | 8 |
对照(1)中的方法,继续排序,可以得到后续结果;
1 | 2 | 6 | 4 | 3 | 7 | 5 | 8 | 11 | 10 | 9 |
(3)当h=1时,我们依次化为十一个子序列,也就是每两个相邻的都得比较。
1 | 2 | 6 | 4 | 3 | 7 | 5 | 8 | 11 | 10 | 9 |
最终结果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
3.C语言版希尔排序
#include<stdio.h>
#include<string.h>
void ShellSort(int *a,int length)
{
int i,j,tmp,h;
for(h=length/2;h>0;h/=2)
{
for(i=h;i<length;i++)
{
tmp=a[i];
for(j=i-h;j>=0;j-=h)
{
if(tmp<a[j])
{
a[j+h]=a[j];
}
else
{
break;
}
}
a[j+h]=tmp;
}
}
}
int main()
{
int i;
int array[10]={1,8,6,7,9,8,6,5,6,2};
ShellSort(array,sizeof(array)/sizeof(array[0]));
for(i=0;i<(sizeof(array)/sizeof(array[0]));i++)
{
printf("%d",array[i]);
}
return 0;
}