【Java】插入排序和希尔排序---图解超详细

目录

插入排序

插入排序的核心图解

希尔排序

希尔排序详细图解


插入排序

插入排序的交换精髓在于 每次随着i的扩大,i走过的路径都是有序的,这和冒泡的思想有异曲同工之处,冒泡是i走一次,数组的最后变成有序的,而插入排序是

插入排序是 i 在前面  j在后面

【Java】插入排序和希尔排序---图解超详细_第1张图片

插入排序的核心图解:

我现在有如下数组:
int []arr ={4,6,9,1,11,5,14,6};

        【Java】插入排序和希尔排序---图解超详细_第2张图片

我们依旧和冒泡排序一样需要两个指针 这次就是 i 和  j

重点在于:每次随着i的扩大,i走过的路径都是有序的

【Java】插入排序和希尔排序---图解超详细_第3张图片

我们发现0到2,也就是前三个都是有序的! 

于是等到i的值为3的时候

注意观测j和i的位置!!!


1是小于9的,所以触发交换

【Java】插入排序和希尔排序---图解超详细_第4张图片

此时发现1还是比前一个 6小 ,所以必须贯彻 每次随着i的扩大,i走过的路径都是有序的


1是小于6的,所以触发交换

【Java】插入排序和希尔排序---图解超详细_第5张图片

 


接着 是1和4的交换

【Java】插入排序和希尔排序---图解超详细_第6张图片


 自此i走过的路程都是有序的了

【Java】插入排序和希尔排序---图解超详细_第7张图片

 


此后就是不断重复这个过程,直到i走到数组的末尾!

整个数组也有序了!

Java代码


    //插入排序
    static  void insertSort(int []arr){

        for (int i = 1; i < arr.length; i++) {

            for (int j = i-1; j >=0; j--) {

                if (arr[j]>arr[j+1]){//判断条件
                    swap(arr,j,j+1);
                }
                else {
                    break;
                }

            }
        }
    }
    //交换函数
    static void swap(int []arr,int x,int y){
        int tmp=arr[x];
        arr[x]=arr[y];
        arr[y] = tmp;
    }

不难看出这个的时间复杂度是O(N^2)

(什么你还不会看时空间复杂度?建议你去b站恶补一下...)


希尔排序

不是这个希尔!

【Java】插入排序和希尔排序---图解超详细_第8张图片

希尔排序,也称为缩小增量排序,是一种基于插入排序的排序算法。它通过比较距离较远的元素,将较小的元素交换到前面,从而逐步减小数组的无序程度,最终实现数组的排序。

她的精髓就在于---分组! 在插入排序的基础上进行分组

一般选择是 将数组分成arr.length/2 然后再把分组范围扩大

比如

第一次这个数组 选择分4组 ,下一次就分成2组

分组后进行选择排序,在数据量小的情况下和插入排序差不多,但是数据量的时候比插入排序快很多

为什么快很多?我也不知道,数学家算出来的,就是快很多

希尔排序的时间复杂度和增量序列的选择有关系,一般情况下希尔排序的时间复杂度为O(n^2) ~ O(n^1.5)。空间复杂度为O(1),是一种原地排序算法。


希尔排序详细图解:

第一次分组,同一个组别的进行选择排序

【Java】插入排序和希尔排序---图解超详细_第9张图片


第二次分组

【Java】插入排序和希尔排序---图解超详细_第10张图片

分组后,排序后的结果

【Java】插入排序和希尔排序---图解超详细_第11张图片

 箭头指向的是交换了的位置


我们发现每次组员都会扩大2倍,这个数组到第3次就变成了进行一次选择排序了

所有的希尔排序,到最后都会进行一次完整的选择排序,但是此时数组已经趋近于有序了


 再来回顾一下

  1. 选择一个增量序列,增量序列是一个数组,一般是按照一定的规则(这里是2)生成的;
  2. 对于每个增量,将数组分为若干个子序列,子序列中的元素相隔增量个位置;
  3. 对每个子序列进行插入排序,即将每个子序列看成一个独立的数组进行插入排序;
  4. 增量为1时,进行一次插入排序,排序结束。

Java代码

  //交换函数
    static void swap(int []arr,int x,int y){
        int tmp=arr[x];
        arr[x]=arr[y];
        arr[y] = tmp;
    }


    //希尔排序
    static  void shellSort(int []arr){
        for (int k= arr.length/2;k > 0; k/=2){//要不要取等号?不用
            for (int i = k; i < arr.length ; i++) {//i和j的范围取值和插入排序一致
                for (int j = i-k; j >=0 ; j-=k) {

                    if (arr[j]>arr[j+k]){
                        swap(arr,j,j+k);
                    }
                    else {
                        break;
                    }
                }
            }
        }

 


【Java】插入排序和希尔排序---图解超详细_第12张图片

哈,谢谢各位同志的阅读,然后呢如果觉得本文对您有所帮助的话,还给个免费的赞捏

Thanks♪(・ω・)ノ

你可能感兴趣的:(排序算法,算法,数据结构)