• 排序算法之希尔排序


    一、原理

    ​ 希尔排序是直接插入排序的一种更高效的改进版本。它把记录按下标的一定增量进行分组,然后对每组使用直接插入排序;随着增量逐渐减少每组中包含的元素越来越多,也越来越有序,当增量减到为1时,整个序列就是一组,排序结束。

    二、代码实现

    package com.jdk8.SortTest;
    
    import java.util.Arrays;
    
    public class ShellSort {
    
        public static void display(int[] arrays){
            for(int i = 0;i < arrays.length;i++){
                System.out.print(" " +  arrays[i] + " ");
            }
        }
    
        public  static void main(String[] argss){
            int[] arrays = {3,9,63,93,72,15,27,86};
            int parition = 2;
            System.out.println("排序前的数据为:");
            display(arrays);
            shellSort(arrays,parition);
            System.out.println();
            System.out.println("排序后的数据为:");
            display(arrays);
        }
    
        public static int[] shellSort(int[] arrays,int parition){
            // i表示希尔排序中的第n/parition+1个元素
            // j表示希尔排序中从0到n/parition+1的元素
            // r表示希尔排序中n/parition+1个元素的值
            int i, j, r, key;
            for(r = arrays.length / parition; r >= 1; r = r / 2) {
                for(i = r; i < arrays.length; i++) {
                    key = arrays[i];
                    j = i - r;
                    // while进行一轮排序
                    while(j >= 0 && key < arrays[j]) {
                        arrays[j+r] = arrays[j];
                        j -= r;
                    }
                    arrays[j+r] = key;
                }
            }
            return arrays;
        }
    }
    

    ​ 运行结果如下:

    排序前的数据为:
     3  9  63  93  72  15  27  86 
    排序后的数据为:
     3  9  15  27  63  72  86  93
    

    三、和直接插入排序对比

    ​ 修改下main函数,修改如下:

        public  static void main(String[] argss){
            int[] arrays = new int[500000];
            for(int i = 0;i < 500000;i++){
                arrays[i] = i + 1;
            }
            int parition = 5;
            long start = (new Date()).getTime();
            shellSort(arrays,parition);
            long end = (new Date()).getTime();
            System.out.println("希尔排序消耗时间为"+(end - start));
        }
    

    ​ 此为正序,对插入排序的main做类似处理。运行五次时间差分别如下:

    直接插入排序:
    15    0    0    0    0
    希尔排序:
    16    15    16    16    15
    

    ​ 倒序情况下:

    直接插入排序:
    47841    47362    47177    47327    47559
    希尔排序:
    32    31    32    32    31
    

    ​ 注:设备为: 处理器为i5-8250U,内存8.00G,64为操作系统。

    ​ 当为正序时直接插入排序比希尔排序快,但是当时倒序时希尔排序比直接快速排序快很多,平均情况下比直接插入排序快。

    四、复杂度分析

    4.1、时间复杂度分析

    ​ 希尔排序的时间复杂度:O(n^(1.3—2))

    4.2、空间复杂度

    ​ 希尔排序的临时变量所占用的空间不随处理数据n的大小改变而改变,即空间复杂度为O(1)。

    五、稳定性

    ​ 希尔排序是不稳定排序。

  • 相关阅读:
    【AT1219】歴史の研究(回滚莫队模板)
    【洛谷4245】【模板】任意模数多项式乘法
    同余与逆元
    线性推逆元
    大整数类型!
    浅谈扩展欧几里得定理(附裴蜀定理)
    二进制串题解(国际考试备用题)
    String 的成员函数
    关于快速幂
    string的赋值
  • 原文地址:https://www.cnblogs.com/ITBlock/p/10409840.html
Copyright © 2020-2023  润新知