JAVA数据结构:希尔排序

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

希尔排序是基于插入排序的以下两点性质而提出改进方法的:
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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值