希尔排序
算法思想:将整个待排序列分割成若干个子序列(由相隔增量个元素组成),分别进行直接插入排序,然后依次缩小增量再进行排序,待整个序列中的元素基本有序时,再对全体元素进行一次直接插入排序。
希尔排序的实现应该由三个循环完成
(1)第一次循环,将增量d依次折半,直到增量d=1
(2)第二三层循环,也就是直接插入排序所需要的两次循环。
算法实现
#include <stdio.h>
#define N 9
int main(void)
{
int arr[N] = {9,1,5,8,3,7,4,6,2};
int d = N / 2; //增量先取一半
int i,j,insertVal;
//希尔排序三层循环
while(d>=1) //当增量大于等于1,不断进行插入排序
{
//一下两层for循环是直接插入排序代码
for(i=d; i<N; i++)
{
insertVal = arr[i];
j = i - d;
while(j>=0 && arr[j]>insertVal)
{
arr[j+d] = arr[j];
j = j - d;
}
arr[j+d] = insertVal;
}
d = d / 2;
}
for(i=0; i<N; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
由如上代码知,希尔排序的关键并不是随便分组后各自排序,而是将相隔某个增量的记录组成一个子序列,实现跳跃式移动,使得排序的效率高。
时间复杂度
时间复杂度为O(n^1.5),要好于直接排序的O(n ^ 2),需要注意的是增量序列的最后一个增量值必须是1.另外由于记录跳跃式的移动,希尔排序并不是一种稳定的排序方法。