【十六】排序算法(二)--希尔排序算法
2015-06-02 19:07
274 查看
1、希尔排序
算法步骤:
通俗的说法:
1. 将一个长度为len的待排序列,依照某个间距gap,分割成len/gap份;
2. 对这每个子序列进行插入排序;
3. 完成后,将gap减小,再执行上述过程;
4. 直到gap为1时,排序完成!
算法实现:
使用上述的实现方法,在排列一个7元素序列时,每个循环的执行次数如下:
可见时间复杂度很高,内层循环居然执行了112次!!
2、已有算法的改进
实际测试:
可见时间复杂度减小了很多,内层循环由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
算法步骤:
通俗的说法:
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
相关文章推荐
- IntentFilter
- QMetaObject分析
- 应用发布到sae问题总结
- python2.7在windows 64bit下的NumPy函数库的安装
- NEUQ 1287: 防御导弹
- 面试题:用最有效的方式算出2*8等于几
- django静态图片配置
- rhel5.8 ISO yum源配置
- jQuery Ztree基本用法
- 【莫比乌斯反演】[BZOJ2301]Problem b
- HDU--2032
- Hadoop技术预览
- 代码学习-Linux内核网卡收包过程(NAPI)
- Matlab画曲线
- android-ioc
- HDU--2032
- Linux 查找具体的文件名称
- Median of Two Sorted Arrays
- 第六章习题汇总
- [转]Android:Layout_weight的深刻理解