希尔排序和插入排序-速度比较(java)

265 篇文章 2 订阅
33 篇文章 0 订阅

希尔排序介绍

希尔排序(Shell Sort)是插入排序的一种改进版本,也称为缩小增量排序。它的基本思想是将待排序的序列划分成若干个子序列,对每个子序列进行插入排序,通过逐步缩小增量的方式,使得整个序列变为有序序列

实现步骤

1.选择一个增量序列,通常选择希尔增量序列,即将待排序序列按照增量序列分成若干个子序列,每个子序列的元素个数相对较少,但是子序列之间的元素相对较多。
2.对每个子序列进行插入排序。插入排序的基本思想是将待排序元素插入到已经排好序的子序列中,不断重复这个过程,直到整个序列变为有序序列。
3.缩小增量序列,重复步骤2,直到增量序列为1。
4.对整个序列进行插入排序。

和插入排序比较的优势:

1.相对于插入排序,希尔排序的平均时间复杂度更低,稳定性更好。
2.希尔排序的空间复杂度通常比插入排序更低,尤其是对于大规模的数据集。
3.希尔排序可以处理部分满序的数据集,即子序列中有一部分元素已经有序,但是整个序列仍然存在较大的间隔。

代码演示希尔排序:

  /**
     * 希尔排序
     * @param arr
     */
    public static void shellSort(int[]arr){
        if (null == arr || arr.length < 2){
            return;
        }
        int[]step = {5,3,1};
        for (int s = 0; s < step.length;s++){
            for (int i = 0;i < arr.length;i++ ){
                for (int j = i - step[s];j >= 0 && arr[j] > arr[j+step[s]] ;j -= step[s]){
                    swap(arr,j,j+step[s]);
                }
            }
        }
    }

和插入排序比较下,看下插入排序的代码

   /**
     * 插入排序
     * @param arr
     */
    public static void insertSort(int[]arr){
        if (null == arr || arr.length < 2){
            return;
        }

        for (int i = 1;i < arr.length;i++){
            for (int j = i - 1; j >=0 && arr[j] > arr[j+1];j--){
                swap(arr,j + 1,j);
            }
        }

    }

对比下两者运行的速度。

1.先生成一个随机数组。

    /**
     * 生成随机数组,
     * @param len 数组最大长度
     * @param max 数组内的最大值
     * @return
     */
    private static int[] generateArray(int len,int max){
        int len1 = (int)(Math.random()*(len + 1));
        int[] arr = new int[len1];
        for (int i = 0; i < arr.length;i++){
            arr[i] =  (int)(Math.random()*(max + 1)) + 1;
        }
        return arr;
    }

2.复制数组

 /**
     * 拷贝数组
     * @param arr
     * @return
     */
    public static int[] copyArr(int[]arr){
        if (null == arr){
            return null;
        }
        int[]copy = new int[arr.length];
        for (int i = 0; i < arr.length;i++){
            copy[i] = arr[i];
        }
        return copy;
    }

3.写个main 方法测试下运行时间比较。


       public static void main(String[] args) {

        //先验证是不是成功。
//        int times = 5000;
//        int len  = 200;
//        int max = 10000;
//        boolean flag = true;
//        for (int i = 0; i < times;i++){
//            int[] ints = generateArray(len, max);
//            int[] copyArr = copyArr(ints);
//            RadixSort(ints);
//            mergeSort(copyArr);
//            if (!isEqual(ints,copyArr)){
//                flag = false;
//                printArr(copyArr);
//            }
//        }
//
//        System.out.println(flag ? "success" : "fail");

          int len1  = 1000000;
        int max1 = 100000;
        int[] ints = generateArray(len1, max1);
        int[] copyArr = copyArr(ints);
        long l = System.currentTimeMillis();
        shellSort(ints);
        long l1 = System.currentTimeMillis();
        System.out.println("希尔排序---数组长度:"+ints.length + " .耗时:"+(l1 - l));
        long l2 = System.currentTimeMillis();
        insertSort(copyArr);
        long l3 = System.currentTimeMillis();
        System.out.println("插入排序---数组长度:"+ints.length + " .耗时:"+(l3 - l2));

    }

耗时结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值