JAVA数据结构:希尔排序

来源:互联网 发布:阿里巴巴排名软件 编辑:程序博客网 时间:2024/05/21 01:56

希尔排序也是插入排序的一种,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:
1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
2.插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

先看一个简单的插入排序

public class InsertSort {    public static void main(String[] args){        int in,out,temp;        int[] a ={12,11,18,19,10,200,49,7}; //final        for(out =1;out<a.length;out++){            temp = a[out];            in = out;            while(in-1>=0&&a[in-1]>=temp){                a[in] = a[in-1];                --in;            }            a[in] = temp;        }        for(int i=0;i<a.length;i++){            System.out.print(a[i]+" ");        }    }}

希尔排序原理

该方法实质上是一种分组插入方法

比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。

假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04。

则取步长gap = 5,分组:

1. (49,13)2. (38,27)3. (65,49)4. (97,55)5. (76,04)

第一次排序列后的结果: 13 27 49 55 04 49 38 65 97 76

gap = gap/2 = 2,分组:

1.(13,49,04,38,97)2.(27,55,49,65,76)

第二次排序后的结果 :04 13 38 49 97 27 49 55 65 76

gap = gap/2 = 1,分组:

1.(04,13,38,49,97,27,49,55,65,76)

第三次排序后的结果 : 04 13 27 38 49 49 55 65 76 97

public class sheetSort {    public static void main(String[] args){        int [] a = {49,38,65,97,76,13,27,49,55,04};        int n = a.length;        sheelSort2(n,a);        for(int i=0;i<a.length;i++){            System.out.print(a[i]+" ");        }    }    public static void sheelSort(int n,int[] a){        int gap,i,in,out;        for(gap = n/2; gap > 0; gap = gap/2){            //分组的数量            for(i=0;i<gap;i++){                //各个组内插入排序                for(out = i + gap ; out < n ; out = out+gap){                    if(a[out]<a[out-gap]){                        int temp = a[out];                        in = out;                        while(in-gap >= 0 &&a[in-gap]>=temp){                            a[in] = a[in-gap];                            in = in - gap;                        }                        a[in] = temp;                    }                }            }        }    }}

优化方法:

先组外同索引的元素进行比较,然后组内比较

public static void sheelSort2(int n,int[] a){        int gap,in,out;        for(gap = n/2; gap > 0; gap = gap/2){                for(out = gap ; out < n ; out ++){                    //插入排序,如果后一个元素小于前一个,那么交换位置                    if(a[out]<a[out-gap]){                        int temp = a[out];                        in = out;                        while(in-gap >= 0 &&a[in-gap]>=temp){                            a[in] = a[in-gap];                            in = in - gap;                        }                        a[in] = temp;                    }                }            }        }

希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。

js实现:

var arr=[49,38,65,97,76,13,27,49,55,04],len=arr.length;for(var fraction=Math.floor(len/2);fraction>0;fraction=Math.floor(fraction/2)){for(var i=fraction;i<len;i++){for(var j=i-fraction;j>=0&&arr[j]>arr[fraction+j];j-=fraction){vartemp=arr[j];arr[j]=arr[fraction+j];arr[fraction+j]=temp;}}}console.log(arr);
原创粉丝点击