基础排序算法三——希尔排序

Posted 聊聊Java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础排序算法三——希尔排序相关的知识,希望对你有一定的参考价值。

基础排序算法三——希尔排序

希尔排序

希尔排序算法是按其设计者希尔(Donald Shell)的名字命名,该算法由1959年公布,是插入排序的一种更高效的改进版本。它的作法不是每次一个元素挨一个元素的比较。而是初期选用大跨步(增量较大)间隔比较,使记录跳跃式接近它的排序位置;然后增量缩小;最后增量为 1 ,这样记录移动次数大大减少,提高了排序效率。希尔排序对增量序列的选择没有严格规定。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
算法思路:

先取一个正整数 d1(d1 < n),把全部记录分成 d1 个组,所有距离为 d1 的倍数的记录看成一组,然后在各组内进行插入排序
然后取 d2(d2 < d1)
重复上述分组和排序操作;直到取 di = 1(i >= 1) 位置,即所有记录成为一个组,最后对这个组进行插入排序。一般选 d1 约为 n/2,d2 为 d1 /2, d3 为 d2/2 ,…, di = 1。

实例分析

假设有数组 array = [80, 93, 60, 12, 42, 30, 68, 85, 10],首先取 d1 = 4,将数组分为 4 组,如下图中相同颜色代表一组:

然后分别对 4 个小组进行插入排序,排序后的结果为:
基础排序算法三——希尔排序

然后,取 d2 = 2,将原数组分为 2 小组,如下图:
基础排序算法三——希尔排序

然后分别对 2 个小组进行插入排序,排序后的结果为:

最后,取 d3 = 1,进行插入排序后得到最终结果:

源码实现

1. java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* @author amosli
* @date 2018-06-14  10:31
*/
public class ShellSort {

   public static void main(String[] args) {
       // 10个数字
       int[] array = new int[]{0, 9, 1, 5, 8, 3, 7, 4, 6, 2};
       sort(array);
   }

   static void sort(int[] array) {
       int len = array.length;
       int gap = len / 2;
       while (gap >= 1) {

           // 5 2 1
           //第一次分组,共5组,组序号为数组下标:0,5 1,6 2,7 3,8 4,9
           //第二次分组,共2组:0,2,4,6,8  1,3,5,7,9
           int total = len / gap;
           for (int i = 0; i < gap; i++) {
               // insertion sort
               //10/5 10/2 10/1
               // 0, 9, 1, 5, 8, 3, 7, 4, 6, 2
               // 0,3 9,7 1,4 5,6 8,2    0 7 1 5 2 3 9 4 6 8
               for (int j = 1; j < total; j++) {
                   int temp = array[j];
                   int k = j - 1;
                   for (; k >= 0 && array[k] > temp; k--) {
                       array[k + 1] = array[k];
                   }
                   array[k + 1] = temp;
               }

           }
           gap = gap / 2;
       }

   }
 }

2. js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function shellSort(array) {
   function swap(array, i, k) {
       var temp = array[i];
       array[i] = array[k];
       array[k] = temp;
   }
   var length = array.length,
       gap = Math.floor(length / 2);
   while (gap > 0) {
       for (var i = gap; i < length; i++) {
           for (var j = i; 0 < j; j -= gap) {
               if (array[j - gap] > array[j]) {
                   swap(array, j - gap, j);
               } else {
                   break;
               }
           }
       }
       gap = Math.floor(gap / 2);
   }
   return array;
}

参考

  • http://bubkoo.com/2014/01/15/sort-algorithm/shell-sort/

  • https://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F#Java


视频:https://youtu.be/ddeLSDsYVp8


以上是关于基础排序算法三——希尔排序的主要内容,如果未能解决你的问题,请参考以下文章

《算法零基础100例》(第41例) 进阶排序 - 希尔排序

重温基础算法内部排序之希尔排序法

《算法零基础100讲》(第38讲) 排序进阶 - 希尔排序

希尔排序图解与代码

基础排序算法总结(代码+图片分析)

希尔排序算法