经典算法(4)-希尔排序

经典算法(4)- 希尔排序

概述

希尔排序是插入排序的一种更高效的改进版本,又称为“缩小增量排序”。它会选定一个增量h,并且按照增量h作为数据分组的依据,对数据进行分组,然后在分好的每一组里面进行插入排序。该轮完成后,就减小增量h,并且h的值最小只能是1,然后重复前面的操作。其实到了希尔排序,概述已经没办法很直观的看出该排序算法是怎么运行的了,但是不用慌,咱还有图解,直接上图解。

图解

在这里插入图片描述
如上图是第一轮的详细过程,原数据是[5,3,8,2,6]初始的增量是h=length/2,即h=5/2=2。假如第一组的第一个索引为0,那么从索引0开始,索引增2即为一组,意思是0,2,4索引的元素标为一组。1,3索引的元素标为一组,那么第一轮[5,8,6]为一组,[3,2]为一组。然后对每一组进行插入排序。第一组[5,8,6],8大于5,所以位置不用更换,6小于8大于5,所以最终的顺序为[5,6,8]。第二组[3,2],2小于3,所以交换位置,最终顺序为[2,3]。然后把两组交换完的数组组合(实际代码里不用分开两组进行排序,所以也就不用组合),即[5,2,6,3,8]。
在这里插入图片描述
如上图是完整的希尔排序,第一轮h为2,把原数据分为两组,排序完的结果为[5,2,6,3,8]。第二轮h为1,即整个数组都是一组,对整个数组进行插入排序,因为第一轮已经对部分排序过了,所以第二轮排序就轻松很多,最终结果为[2,3,5,6,8]。

代码

public void sort(int[] array){
        int h = 1;
        //选出h,上图为了方便所以初始h就选为length/2
        while(h<array.length/2){
            h = h*2+1;
        }
        //排序
        while(h>=1){
            //希尔排序
            //找到待插入的元素,默认第一个数是已经排序的,所以未排序的从h开始往后,h以前的都是分组的第一个数
            for (int i = h; i < array.length; i++) {
                //j = i,每次循环i都会增加,先从每组的第二个数开始排序,等i增加到h+h时就轮到第三个数排序
                for (int j = i; j >= h; j-=h) {
                    //j-h可认为第二个数要与第一个对比,则
                    if(array[j-h]>array[j]){
                        int temp = array[j-h];
                        array[j-h] = array[j];
                        array[j] = temp;
                    }else{
                        break;
                    }
                }
            }
            //h递减
            h = h/2;
        }
    }

时间复杂度

希尔排序的时间复杂度网上有比较多的版本,但是最多的版本是O( n 1.3 n^{1.3} n1.3),它的性能比O( n 2 n^2 n2)快很多,不过是一个不稳定的排序算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值