算法--排序算法的介绍与总结(四)
来源:互联网 发布:怎样给淘宝客服发图片 编辑:程序博客网 时间:2024/05/16 09:51
上一篇文章介绍了堆排序,这篇文章介绍下shell排序算法。
2.7、Shell排序算法
在介绍shell排序算法之前,我们先回顾下直接插入排序算法的流程:
1、首先对数组的前两个数据进行从小到大的排序。
2、接着将第3个数据与排好序的两个数据比较,将第3个数据插入合适的位置。
3、然后将第4个数据插入已排好序的前3个数据中
4、不断重复上述过程,直到把最后一个数据插入合适的位置。最后便完成了对原始数组从小到大的排序。
由插入排序算法的流程我们可以知道:每次向已排好序的数据中插入一个新的数据时,新插入的数据都要跟已排好序的数据一一比较,直到找到自己的位置。如果数据量比较大,数据比较的次数较多影响效率。shell排序算法也用到了上面的直接插入排序算法,但是每一次使用直接插入排序算法时,数组中的数据已经是基本有序的了,这就大大提高了排序的效率。
实现思路:
1、将有n个元素的数组分成n/2个数字序列,第1个数据和第n/2+1个数据为一对,后面的一次类推(即分组)。
2、一次循环使每一个序列对排好顺序(使用直接排序算法)。
3、然后再变为n/4个序列(分组数目变少,每组中的数据变多),再排序。
4、不断重复上述过程,随着序列分组变成了一个,数据也完成了排序。
举一个例子来帮助大家理解:现在有一个10个元素的数组:int[] a = {4,6,7,1,2,5,3,9,8,0};
第一步:n=10,n=n/2=5,那也就是说10个元素分成5组,每组两个,组距为5。即4、5一组,6、3一组,7、9一组,1、8一组,2、0一组。
第二步:对这五组数据分别排序:
4<5:不用交换。
6>3:6与3交换(即a[1]=3,a[6] = 6)。
7<9:不用交换。
1<8:不用交换。
2>0:交换(a[5]=0,a[9]=2)
最后的结果为:4,3,7,1,0,5,6,9,8,2
第三步:n = n/2 = 5/2 = 2,将第二步的数组分为2组,每组5个数据,组距为2。即:
第一组:4 7 0 6 8
第二组: 3 1 5 9 2
对每一个分别排序,结果为:
第一组0 4 6 7 8
第二组:1 2 3 5 9
这一步完成后的记过为:0,1,4,2,6,3,7,5,8,9
第四步:n = n/2 = 2/2 = 1。将第三步的数据分成一组(已不用分了)
再对数据进行排序,结果为:0,1,2,3,4,5,6,7,8,9
上述分析过程对应的代码如下,代码可以直接运行,而且对每一步的中间结果都输出了,方便大家查看
/** * @author Mr0 * describe:使用shell插入排序时,如果原数据已经是基本有序的,则排序的效率可以大大的提高。 * 另外,对于数据量较小的序列使用直接插入排序,因需要移动的数据量较少,其效率也较高。 * 因此shell排序算法具有比较高的排序效率。 * */public class P4_4_Insert_ShellSort {static final int SIZE =10; /** * @return */ static int geneNum(){ int tempNum =(int)(Math.random()*100.0); return tempNum; } /** * @param a */ static void shellSort(int[] a){ int r; int x=0; for(r=a.length/2;r>=1;r/=2){ //分组,r是组距,也是组数。 for(int i=r;i<a.length;i++){ //在每一组内部利用插入算法排序 int temp=a[i]; int j=i-r; while(j>=0 && temp<a[j]){ a[j+r] = a[j]; j-=r; } a[j+r] = temp; } x++; System.out.print("第"+x+"步排序结果为:"); for(int k=0;k<a.length;k++){ System.out.print(a[k]+" "); } System.out.print("r=" + r); System.out.print("\n"); } } public static void main(String[] args){ //int[] array = new int[SIZE];// for(int i=0;i<10;i++){// array[i]= P4_4_Insert_ShellSort.geneNum();// } int[] array = {4,6,7,1,2,5,3,9,8,0}; System.out.print("排序前的数组为:"); for(int i=0;i<array.length;i++){ System.out.print(array[i]+" "); } System.out.print("\n"); P4_4_Insert_ShellSort.shellSort(array); System.out.print("排序后的数组为:"); for(int i=0;i<array.length;i++){ System.out.print(array[i]+" "); } }}
- 算法--排序算法的介绍与总结(四)
- 算法--排序算法的介绍与总结(一)
- 算法--排序算法的介绍与总结(二)
- 算法--排序算法的介绍与总结(三)
- 算法--排序算法的介绍与总结(五)
- 排序算法总结(四)
- 排序算法四总结
- 排序算法总结(四)希尔排序
- 常用排序算法总结(四)
- 排序算法 种类 总结 介绍
- 常用算法总结之排序(四)----快速排序
- Java排序算法总结(四):希尔排序
- Java排序算法总结(四):希尔排序
- 常见排序算法的总结与比较
- 七大排序算法的研究与总结
- 各种排序算法的总结与比较
- 排序算法的详解与总结
- 排序算法(四)快速排序算法
- Qualcomm MSM Camera Dtsi documentation - thjfk
- Struts2访问Servlet API的三种方式
- JSP项目中文乱码完全解决方案
- 闲暇之余有必要再回顾一下经典排序,理一理哈。
- 面试题
- 算法--排序算法的介绍与总结(四)
- Linux守护进程
- C - Spanning Tree 最小生成树 Kruskal (第四届华中区程序设计邀请赛暨武汉大学第十三届校赛)
- #笔记#圣思园 JavaSE 第39讲——ArrayList源代码剖析
- PHP正则表达式(常用的7个例子)
- 使用gradle来构建Spring boot时遇到的问题
- 习题2-14
- Xcode6.2版本详解
- WEB开发文档2 总结