您的位置:首页 > 其它

【十六】排序算法(二)--希尔排序算法

2015-06-02 19:07 274 查看
1、希尔排序



算法步骤:

通俗的说法:

1. 将一个长度为len的待排序列,依照某个间距gap,分割成len/gap份;

2. 对这每个子序列进行插入排序;

3. 完成后,将gap减小,再执行上述过程;

4. 直到gap为1时,排序完成!

算法实现:

/*
用于交换两个元素的值
*/
void swap(int *array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}


/*
希尔排序算法
通俗的说法:
将一个长度为len的待排序列,依照某个间距gap,分割成len/gap份,对这每个子序列进行插入排序;
完成后,将gap减小,再执行上述过程;
直到gap为1时,排序完成!
*/
void ShellSort(int *array, int len)
{
int i = 0, j = 0;
int gap = len;
int k = 0;
int z = 0;

#ifdef _STATISTICS_
//添加宏定义:_STATISTICS_,可统计三个循环的执行次数
int jsum = 0;
int isum = 0;
int zsum = 0;
#endif

do
{
gap = gap / 3 +1;
for(z = 0; z < (len / gap) + 1; z++)
{
for(i = z + gap; i < len; i+=gap)
{
k = i;
for(j = i-gap; j>=0; j-=gap)
{
if(array[k] < array[j])
{
swap(array,j,k);
k = j;
}
#ifdef _STATISTICS_
jsum++;
#endif
}
#ifdef _STATISTICS_
isum++;
#endif
}
#ifdef _STATISTICS_
zsum++;
#endif
}
}while(gap > 1);

#ifdef _STATISTICS_
printf("jsum=%d\tisum=%d\tzsum=%d\t\n",jsum,isum,zsum);
#endif
}


使用上述的实现方法,在排列一个7元素序列时,每个循环的执行次数如下:



可见时间复杂度很高,内层循环居然执行了112次!!

2、已有算法的改进

/*
希尔排序算法
对上述ShellSort实现的改进:
按照上面的描述来说,假如一个待排序列被分割成了3个子序列,那么理应循环3次,分别对
这3个子序列进行插入排序,然后再使gap减小,再进行下一次分割和排序,但是这样写,上方
的三个函数的执行次数会很多,算法的时间复杂度很高!
改进:
因为希尔排序算法,当gap为1时,实际上就是一个插入排序算法,也就是说,无论如何,一旦
gap为1,序列就能被排好,所以再待排序列被分割成几个子序列后,我们可以只做第一个子序
列的插入排序工作,这样能很好的减少算法的时间复杂度,也就少了一层循环!
*/
void Shell_Sort(int *array, int len)
{
int i = 0, j = 0;
int gap = len;
int k = 0;

#ifdef _STATISTICS_
//添加宏定义:_STATISTICS_,可统计三个循环的执行次数
int jsum = 0;
int isum = 0;
int zsum = 0;
#endif

do
{
gap = gap / 3 +1;
for(i = gap; i < len; i+=gap)
{
k = i;
for(j = i-gap; j>=0; j-=gap)
{
if(array[k] < array[j])
{
swap(array,j,k);
k = j;
}
#ifdef _STATISTICS_
jsum++;
#endif
}
#ifdef _STATISTICS_
isum++;
#endif
}
#ifdef _STATISTICS_
zsum++;
#endif
}while(gap > 1);

#ifdef _STATISTICS_
printf("jsum=%d\tisum=%d\tzsum=%d\t\n",jsum,isum,zsum);
#endif
}


实际测试:



可见时间复杂度减小了很多,内层循环由112次减少到了30次!!

3、完整源码下载

文件名:shellSort-1.0.tar.gz

链接: http://pan.baidu.com/s/1dDjfTRz 密码: 9z2c

编译步骤:

0.1 解压缩:tar -zxvf shellSort-1.0.tar.gz

0.2 编译:gcc -std=c99 -Wall -g shellSort.c -o shellSort

0.3 运行:./shellSort
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: