• 排序算法之希尔排序


    一、原理

    ​ 希尔排序是直接插入排序的一种更高效的改进版本。它把记录按下标的一定增量进行分组,然后对每组使用直接插入排序;随着增量逐渐减少每组中包含的元素越来越多,也越来越有序,当增量减到为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)。

    五、稳定性

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

  • 相关阅读:
    TXSQL:云计算时代数据库核弹头——云+未来峰会开发者专场回顾
    游戏场景下的DDoS风险分析及防护
    一站式机器学习平台TI-ONE是什么?——云+未来峰会开发者专场回顾
    带有Apache Spark的Lambda架构
    攻克数据库核心技术壁垒,实现百万级QPS的高吞吐
    想学大数据?大数据处理的开源框架推荐
    可怕!数据库竟然打破安迪-比尔定律
    什么?云数据库也能C位出道?
    协同过滤的R语言实现及改进
    Android代码规范----按钮单击事件的四种写法
  • 原文地址:https://www.cnblogs.com/ITBlock/p/10409840.html
Copyright © 2020-2023  润新知