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

文章目录

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

插入排序

插入排序就是从前向后(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;
        }
    }
相关推荐
vibecoding日记14 小时前
双非如何快速入职字节等大厂大模型?真实案例分析:推理优化和投机解码
算法·求职·大模型工程师
yszaygr213816 小时前
Verilog参数化游程编码RLE模块
算法
望易16 小时前
刚设计的大模型架构-双域耦合认知框架
算法·架构
复杂网络20 小时前
多个 Claude Code 与多个 Codex 协同工作:设计与实现方案
算法
HjhIron1 天前
面试常客:字符串算法从入门到进阶
算法·面试
吴佳浩2 天前
DeepSeek DSpark:Confidence-Scheduled Speculative Decoding 技术解析
人工智能·算法·deepseek
触底反弹2 天前
🧠 搞懂 Token,才算真正入门大模型——从分词原理到 Embedding 语义实战
javascript·人工智能·算法
vivo互联网技术2 天前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
浮生望2 天前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法