数据结构-希尔排序(Java实现)

希尔排序 对插入排序的优化
因为当如果插入排序中最小的元素位于最后一位时,就需要不断的进行循环判断,直到第一位,非常影响效率

package datastructure.sort;

/*
    @CreateTime 2021/9/13 11:12
    @CreateBy cfk
*/

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class ShellSort {



    public static void main(String[] args) {
        // 测试80000条数据 冒泡排序所需要的时间
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int) (Math.random()*8000000);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
        String s1 = sdf.format(new Date());
        System.out.println(s1);


        shellChange(arr);


        String s2 = sdf.format(new Date());
        System.out.println(s2);


        // int[] arr = {1,0,5,7,8,4,6,9,2,3};
        //
        // moveShell(arr);
        //
        // System.out.println(Arrays.toString(arr));
    }


    //按照一定的步长通过交换法完成数组的插入   遍历80000数据7s
    public static void shellChange(int[] arr){

        //每次以数据一半作为步长 进行判断
        for (int step = arr.length/2; step > 0; step /= 2){
            int tmp;
            //从步长后半段数据开始遍历
            for (int i = step; i < arr.length; i++) {
                //以同样的步长进行遍历
                for (int j = i - step; j >= 0; j -= step) {
                    //如果当前元素对应步长后的元素大 则更换两者的位置
                    if (arr[j] > arr[j+step]){
                        tmp = arr[j];
                        arr[j] = arr[j+step];
                        arr[j+step] = tmp;
                    }

                }
            }
        }


    }

    //按照一定的步长通过交换法完成数组的插入   遍历80000数据6s
    public static void shellChange2(int[] arr){

        //Knuth 克努特 序列选取间隔 提高效率
        int jiange = 1;
        while (jiange<= arr.length/3){
            jiange = jiange*3+1;
        }

        //每次以数据一半作为步长 进行判断
        for (int step = jiange; step > 0; step = (step-1)/3){
            int tmp;
            //从步长后半段数据开始遍历
            for (int i = step; i < arr.length; i++) {
                //以同样的步长进行遍历
                for (int j = i - step; j >= 0; j -= step) {
                    //如果当前元素对应步长后的元素大 则更换两者的位置
                    if (arr[j] > arr[j+step]){
                        tmp = arr[j];
                        arr[j] = arr[j+step];
                        arr[j+step] = tmp;
                    }

                }
            }
        }


    }




    //按照一定的步长通过交换法完成数组的插入   遍历80000数据1s
    public static void moveShell(int[] arr){

        for(int step = arr.length/2; step > 0; step /= 2){

            for (int i = step; i < arr.length; i++) {
                //把需要插入的元素保存在一个变量里
                int insertVal = arr[i];
                //给被插入元素一个初值
                int insertIndex = i - step;
                //只有当后面的元素小于前面的元素时才进行此运算 这里主要为了避免如果已经按顺序排列了在排序
                if (arr[insertIndex+step]<arr[insertIndex]){
                    //如果被插入数 相隔同样 步长还有数据则进行下面的运算
                    while (insertIndex >= 0 && insertVal < arr[insertIndex]){
                        arr[insertIndex+step] = arr[insertIndex];
                        insertIndex -= step;
                    }
                    //当退出while,就把temp赋值
                    arr[insertIndex+step] = insertVal;
                }

            }

        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值