【排序】插入排序 & 希尔排序(改进)

文章目录

以从小到大排序为例进行说明。

插入排序

插入排序就是从前向后(i=1开始)进行选择,如果找到在i之前(分配一个j下标进行寻找)有比array[i]大的数据,那就将其移动到后面(j+1处),每次小循环直到j < 0为止,大循环直到i > array.length为止。

  • 小循环就是将i前面的元素进行遍历找出大的元素
  • 大循环就是遍历整个数组将i处的元素进行插入调整

时间复杂度

O(n2)

最坏的情况是:i 顺着把整个数组遍历一遍的同时,j 向前遍历每次都需要遍历至 -1;这样就会遍历n2

  • 所以插入排序最快是排一个有序的数组,每次都不同调,是O(n)
  • 最慢是排一个逆序的数组,每次都需要遍历,是O(n2)

空间复杂度

O(1)

没有额外的空间消耗

代码

java 复制代码
public void insertSort(int[] array) {
        // 从1开始是因为一个元素必定是有序的
        for (int i = 1; i < array.length; i++) {
            // 保存下来用于比较,不然i下标的值可能会由于j+1的赋值而发生改变
            int tmp = array[i];
            // 从i的前一个开始比较
            int j = i - 1;
            for (; j >= 0; j--) {
                if (array[j] > tmp) {
                    // 如果比 tmp 大,那就应该将前一个数据挪到后一个
                    array[j+1] = array[j];
                } else {
                    // 如果小于等于,那就说明从这个j开始前面的都是有序的,不需要再遍历了
                    break;
                }
            }
            // 	循环结束后,插入 tmp 的值
            array[j+1] = tmp;
        }
    }

希尔排序

希尔排序是对于插入排序的改进,通过改变每次插入排序的间隔增量而达到优化的一种排序。

该排序定义了一个gap 用于标识每次插入排序的分组,其余于与插入排序无异。

时间复杂度

O(n1.3) ~ O(n1.5)

由于gap 的不同会导致排序的趟数不同,所以该算法并没有一个明确的时间复杂度。

空间复杂度

O(1)

没有额外空间开销

代码

java 复制代码
public void shellSort(int[] array) {
        int gap = array.length;
        // 循环每次的以gap为增量的插入排序
        while (gap != 1) {
            gap /= 2;
            shellSort(array, gap);
        }
    }

    private void shellSort(int[] array, int gap) {
    	// i+=gap也可以,因为最后gap传进来总会是1,会进行一次完全态的插入排序
        for (int i = 0; i < array.length; i++) {
            int tmp = array[i];
            int j = i - gap;
            // 这里就是对间隔为 gap 的数据进行比较和插入
            for (; j >= 0; j += gap) {
                if (array[j] > tmp) {
                    array[j + gap] = array[i];
                } else {
                    break;
                }
            }
            // 与普通插入排序相同,需要在最后将被比较的数据还到该去的地方
            array[j+gap] = tmp;
        }
    }
相关推荐
二进制person几秒前
Java SE--方法的使用
java·开发语言·算法
OneQ66627 分钟前
C++讲解---创建日期类
开发语言·c++·算法
JoJo_Way33 分钟前
LeetCode三数之和-js题解
javascript·算法·leetcode
.30-06Springfield1 小时前
人工智能概念之七:集成学习思想(Bagging、Boosting、Stacking)
人工智能·算法·机器学习·集成学习
凌肖战3 小时前
力扣网C语言编程题:在数组中查找目标值位置之二分查找法
c语言·算法·leetcode
weixin_478689763 小时前
十大排序算法汇总
java·算法·排序算法
luofeiju4 小时前
使用LU分解求解线性方程组
线性代数·算法
学不动CV了4 小时前
数据结构---线性表理解(一)
数据结构
SKYDROID云卓小助手4 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
ysa0510305 小时前
数论基础知识和模板
数据结构·c++·笔记·算法