希尔排序算法
来源:互联网 发布:一般纳税人 报税软件 编辑:程序博客网 时间:2024/05/29 19:43
对于直接插入排序,当序列长度较小时,排序的效率较高;当n较大时,若序列已基本有序,排序的效率也较高,其效率可以达到O(n);当n较大且无序时,直接插入排序的效率就较低,这时,如果能将序列分成几个较小的序列,对这些较小的序列先排序, 再对较长的序列进行排序,就可以一定程度地提高排序的效率,这就是希尔排序的基本思想。
希尔排序是一种不稳定的排序算法。希尔排序需要一个存储单元的辅助空间,而且时间性能与增量因子di步长有直接关系,对于不同的步长,时间复杂度不一样,目前还没有人给出选取最好步长的方法。选取步长增量序列的取法很多,有取奇数的,有取质数的,但无论怎么取,都必须满足这样一个规则:最后一个步长一定为1。
public static void main(String args[]){int a[] ={0,9,5,6,10,2,7,8};int d[] = {5,3,1};//directInsertSort(a);//binaryInsertSort(a);ShellInsertSort(a,d);}
/* * 希尔排序算法 * 算法思想:先取一个小于n的整数di(步长),然后把待排序的序列分成di个组,从第一个记录开始,间隔为di的记录为同一组,分组完成之后,在每一组中采用直接插入排序或者二分插入排序进行排序。 * 减小步长,再进行分组,再排序,序列的有序性进一步得到改善,直到di=1,即为直接插入排序,此时排序完成。 * 参数:a[]为要排序的数组,d[]为所取得步长(步长从大到小取) */ public static void ShellInsertSort(int a[],int d[]){ int di;//步长 int a_length = a.length;//数组a[]的长度 for(int i=0;i<d.length;i++){ di = d[i];//从d[]中取出步长的大小 for(int j=1;j<= di;j+=1){//按步长大小计算a[]中开排序的位置,开始位置为a[j],结束位置为a[j+di],总共会进行di次分组 if((j+di) >=a_length){//先判断数组是否会越界 break; } int sIndex = j;//开始位置 int eIndex = j+di;//结束位置 while(eIndex<a_length){//当结束位置小于数组长度时,才进行二分插入排序,排序完成之后,增加下标的值 printArray("di:" + di +",sIndex:" + sIndex +",eIndex:" + eIndex+",:" , a); binaryInsertSort(a, sIndex, eIndex); sIndex += di; eIndex += di; } } } }
//二分插入排序//与直接插入排序算法类似,不同之处在于确定好插入的位置之后,一次性地将数据往后移动。//参数:a[]排序的数组,startIndex开始排序的下标,endIndex结束排序的下标public static void binaryInsertSort(int []a,int startIndex,int endIndex){if(startIndex > endIndex){//判断下标System.out.println("开始下标大于结束下标");return;}if(endIndex >= a.length){//判断下标是否越界System.out.println("结束下标大小大于数组大小");return;}printArray("开始二分插入排序:", a);for(int i=startIndex+1;i<endIndex+1;i++){//开始下标第一位作为有序序列,从开始下标第二位开始排序//如果有序的最后一位大于要排序的一位,将其加入标记位a[0]if(a[i-1]>a[i]){a[0] = a[i];printArray("将第"+i+"位放入标记位:",a); //用二分方式查找要插入的位置(将有序的队列的中间值与要插入的数据比较。如果大,则继续从中间值的右边继续二分查找;如果小,则从中间值的左边开始(相等的情况应该默认为大),以此类推)int low = 1;int high = i-1;while(high>=low){int mid = (low + high)/2;//如果插入数据比中间值大if(a[0]>=a[mid]){low = mid+1;}elsehigh = mid-1;}printArray("用二分法查找到插入数据的位置为"+(high+1)+":",a);//跳出循环之后,要插入的位置为high+1(如果不明白的话自己可以尝试一下,假如最后a[0]判断为在a[3]和a[4]之间,这时low=3,mid=3,high=4)//假如a[0]<a[3],则进入else,low=3,mid=3,high=2,跳出循环,要插入数据位置为3//假如a[3]<a[0]<a[4],则进入if,low=4,mid=3,high=4,进入else,low=4,mid=4,high=3,跳出循环,要插入数据位置为4//假如a[4]<a[0],则进入if,low=4,mid=3,high=4,进入if,low=5,mid=4,high=4,跳出循环,要插入的位置为5int j;for( j = i-1; j>=high+1;j--){//向后移动数据a[j+1] = a[j];}a[j+1] = a[0];printArray("插入数据后的结果为:",a);}}System.out.println("-------------");}
最后看实现的结果:
0 0
- 排序算法--希尔排序
- 排序算法-希尔排序
- 排序算法--希尔排序
- 排序算法--希尔排序
- 排序算法---希尔排序
- 排序算法---希尔排序
- 排序算法--希尔排序
- 排序算法--希尔排序
- 排序算法:希尔排序
- 排序算法:希尔排序
- 【排序算法】希尔排序
- 排序算法---希尔排序
- 排序算法:希尔排序
- 排序算法-希尔排序
- 排序算法---希尔排序
- 排序算法-- 希尔排序
- 排序算法-希尔排序
- 排序算法:希尔排序
- Web安全测试之XSS
- java中的包装类
- Xcode中的Info.plist字段列表详解
- 【OpenCV入门指南】第十一篇 鼠标绘图
- 【OpenCV入门指南】第十二篇 在Windows平台下分享OpenCV程序
- 希尔排序算法
- Servlet练习--提交表单
- 右侧导航栏的添加
- ArcGIS OD矩阵批量处理最短路径
- 【OpenCV入门指南】第十三篇 人脸检测
- 每天一条linux---chown命令
- 图像处理与计算机视觉学习资源
- 【60.97%】【BZOJ 1925】 [Sdoi2010]地精部落
- TCP三次握手连接建立和四次交互关闭连接