• 数据结构和算法(三)希尔排序


    希尔排序

    希尔排序是一种基于插入排序的排序算法。对于大规模的乱序数组,插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点从数组的一端移动到另一端。希尔排序为了加快速度简单的改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序

    希尔排序的思想是使数组中任意间隔为h的元素都是有序的。这样的数组被称为“h有序数组”。换句话说,一个h有序数组就是h个相互独立的有序数组编织在一起组成的一个数组。在进行排序时,如果h很大,就能将元素移动到很远的地方,为实现更小的h有序创造方便。

     1 public static void sort(Comparable[] a) {
     2         //将a按升序排列
     3         int L = a.length;
     4         int h = 1;
     5         while (h < L / 3) {
     6             h = 3 * h + 1;
     7         }
     8         while (h >= 1) {
     9             //将数组变为h有序
    10             for (int i = h; i < L; i++) {
    11                 for (int j = i; j >= h && (a[j].compareTo(a[j - h]) < 0); j -= h) {
    12                     Selection.exch(a, j, j - h);
    13                 }
    14             }
    15             h = h / 3;
    16         }
    17 
    18     }

    增量:

    在上面这段代码中,使用了序列1/2(3k-1),从N/3开始递减至1,这个序列叫递增序列。

    在希尔排序中,最常用的递增序列是希尔增量(N/2),这个最常用但不是最好的。最坏的情况时间复杂度仍为O(n²)。Hibbard增量序列(2k1),最坏时间复杂度为O(N3/2),平均时间复杂度为O(N5/4);Knuth增量序列 1/2(3k-1)。

    实现希尔排序的一种方法是对于每个h,用插入排序将h个子数组独立的排序,但因为子数组是相互独立的,一个更简单的方法是在h到子数组中将每个元素交换到比它大的元素之前去(将比它大的元素向右移动一格)。只需要在插入排序的代码中将移动元素的距离由1改为h即可。

    希尔排序更高效的原因是它权衡了子数组的规模和有序性。排序初,各个子数组都很短,排序后子数组都是部分有序,这两种情况都很适合插入排序。

    结论: 希尔排序比插入排序和选择排序更高效,并且数组越大,优势越大。且代码量小,不需要使用额外的内存空间。

  • 相关阅读:
    web设计_6_图片/标题/说明文字布局
    web设计_5_自由的框式组件
    web设计_4_可扩展的行
    ubuntu下把python脚本转为二进制字节码文件
    Ubuntu与Window双系统安装的注意事项
    安装Windows和Ubuntu双系统2
    安装Windows和Ubuntu双系统
    Configuring and Running Django + Celery in Docker Containers
    ggplot绘图之基本语法
    R Multiple Plots
  • 原文地址:https://www.cnblogs.com/yushangzuiyue/p/8563310.html
Copyright © 2020-2023  润新知