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

文章目录

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

插入排序

插入排序就是从前向后(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;
        }
    }
相关推荐
聚客AI21 小时前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了1 天前
AcWing学习——双指针算法
c++·算法
moonlifesudo1 天前
322:零钱兑换(三种方法)
算法
NAGNIP2 天前
大模型框架性能优化策略:延迟、吞吐量与成本权衡
算法
美团技术团队2 天前
LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
人工智能·算法
Fanxt_Ja2 天前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法