算法--排序算法的介绍与总结(四)

来源:互联网 发布:怎样给淘宝客服发图片 编辑:程序博客网 时间: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]+" ");        }    }}
0 0
原创粉丝点击