图片转载于https://www.cnblogs.com/chengxiao/p/6104371.html

1、什么是希尔排序?

希尔排序也是一种插入排序,他是第一个打破时间复杂度O(n^2)的排序方法,它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序

2、希尔排序的思想:

希尔排序是把元素按下标的一定增量进行分组,对每组使用直接插入排序算法排序;

随着增量逐渐减少,当增量减至 1 时整个文件恰被分成一组,算法便终止

3、代码逐步实现:

排序的元素:
int[] arr={8,9,1,7,2,3,5,4,6,0};

3.1 交换法实现

//第一步 
for (int i=5;i<arr.length;i++){ //i的初始值为初始增量 10/2=5,分为5组,每组两个元素
            for (int j=i-5;j>=0;j-=5){  //j是距离i为5元素,那么,0和5一组,6和2一组,以此类推,每组比完之后,回退到上一组重新比较,具体用法看第二轮
                if (arr[j+5]<arr[j]){  //比较大小,交换
                    temp=arr[j];
                    arr[j]=arr[j+5];
                    arr[j+5]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
//第二次
        for (int i=2;i<arr.length;i++){ //这里的2是上次的5/2=2,所以分为两组,一组5个
            for (int j=i-2;j>=0;j-=2){//距离为2的元素,j-=2是每次比完这一轮重新指向上一分组比较,例如[3,1]和[1,0]两组,比完[1,0]是[0,1],在和前面比较排序,最后为[0,1,3]
                if (arr[j+2]<arr[j]){
                    temp=arr[j];
                    arr[j]=arr[j+2];
                    arr[j+2]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
 //第三次
        for (int i=1;i<arr.length;i++){ //i是2/2=1,一共是一组
            for (int j=i-1;j>=0;j-=1){
                if (arr[j+1]<arr[j]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

最后把上面的代码整合起来:

 //汇总(交换法,花费时间长)
        for (int a=arr.length/2;a>0;a/=2){  //a是增量
            for (int i=a;i<arr.length;i++){
                for (int j=i-a;j>=0;j-=a){
                    if (arr[j+a]<arr[j]){
                        temp=arr[j];
                        arr[j]=arr[j+a];
                        arr[j+a]=temp;
                    }
                }
            }
            System.out.println(Arrays.toString(arr));

上面才用交换的方式实现的排序花费时间大,不推荐使用,按照交换的思路继续,替换成插入法

3.2 插入法实现:

 1  //汇总(基于插入,花费时间短)
 2         for (int gap=arr.length/2;gap>0;gap/=2){
 3             for (int i=gap;i<arr.length;i++){
 4                     int j=i-gap;
 5                     int temp=arr[i];
 6                     while (j>=0 && temp<arr[j]){
 7                         arr[j+gap]=arr[j];
 8                         j-=gap;
 9                 }
10                     arr[j+gap]=temp;
11             }
12             System.out.println(Arrays.toString(arr));
13 
14         }

从3-10行都是插入法来实现的,可以看出,希尔排序就是对排序的元素进行分组,大大提升了时间

4、时间复杂度

O(n^(1.3—2))

 5、希尔的优势

希尔排序其实就是在插入排序的基础上,增加了一个增量,每次为元素划分不同的组
希尔排序在无序的时候,分组多,每个组元素少
随着增量的变化,分组变少,每个组内元素增加,但组内元素也逐渐变得有序
所以排序起来快(如果原始数据的大部分元素有序,那么插入排序会很快)

版权声明:本文为han200113原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/han200113/p/11722999.html