算法【4】:希尔排序(缩小增量排序)
2015-12-15 14:09
169 查看
插入排序的算法复杂度为O(n2),但如果序列为正序可提高到O(n),而且直接插入排序算法比较简单,希尔排序利用这两点得到了一种改进后的插入排序。
或者
一. 算法描述
希尔排序将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。二,增量的选择
在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化。一般首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;下图详细讲解了一次希尔排序的过程:二. 算法分析平均时间复杂度:希尔排序的时间复杂度和其增量序列有关系,这涉及到数学上尚未解决的难题;不过在某些序列中复杂度可以为O(n1.3);#define MAXNUM 10 void main() { void shellSort(int array[],int n,int t);//t为排序趟数 int array[MAXNUM],i; for(i=0;i<MAXNUM;i++) scanf("%d",&array[i]); shellSort(array,MAXNUM,int(log(MAXNUM+1)/log(2)));//排序趟数应为log2(n+1)的整数部分 for(i=0;i<MAXNUM;i++) printf("%d ",array[i]); printf("\n"); } //根据当前增量进行插入排序 void shellInsert(int array[],int n,int dk) { int i,j,temp; for(i=dk;i<n;i++)//分别向每组的有序区域插入 { temp=array[i]; for(j=i-dk;(j>=i%dk)&&array[j]>temp;j-=dk)//比较与记录后移同时进行 array[j+dk]=array[j]; if(j!=i-dk) array[j+dk]=temp;//插入 } } //计算Hibbard增量 int dkHibbard(int t,int k) { return int(pow(2,t-k+1)-1); } //希尔排序 void shellSort(int array[],int n,int t) { void shellInsert(int array[],int n,int dk); int i; for(i=1;i<=t;i++) shellInsert(array,n,dkHibbard(t,i)); } //此写法便于理解,实际应用时应将上述三个函数写成一个函数。
或者
while(true) { for(int i=0;i<d;i++) { for(int j=i;j+d<a.length;j+=d) { int temp; if(a[j]>a[j+d]) { temp=a[j]; a[j]=a[j+d]; a[j+d]=temp; } } } if(d==1){break;} d = (int)d/2; }
相关文章推荐
- Varnish简介
- 关于Linux的Jiffies/Tick/HZ
- ios 3D引擎 SceneKit 开发(1) --起始篇
- IOS开发中emoji表情如何判断
- JavaScript如何获取网页url中的参数
- 分享功能注意点
- Mac 在命令行中获得Root权限
- 比较容易混淆的模式
- Linux每日学习(二)
- Android:Service 随记
- java调用R语言包(JRI方式),bug记录
- GitHub for Visual Studio使用讲解
- Linux makefile 文件
- PHP页面间参数传递的四种方法详解
- OpenGL中FBO的概念及其应用 [转]
- JVM虚拟机---在centos下安装及编译openjdk
- CSR MESH修改串口波特率方法!
- 应届Java小菜鸟初到公司之环境部署
- 常用算法和排序
- Properties读取配置文件