基础算法-插入排序

插入排序 (Insertion Sort)

像"打扑克牌时理牌"一样,每次从手里还没排好的牌中抽出一张,从右往左和已经排好的牌挨个比较,找到合适的位置插进去,让手里的牌始终保持有序。

核心代码

c 复制代码
#include <stdio.h>

// 插入排序函数
void insertionSort(int arr[], int n) {
    // 外层循环:从第二个元素开始,逐个处理未排序部分的元素
    for (int i = 1; i < n; i++) {
        int key = arr[i]; // 取出当前需要插入的元素(相当于抽出一张扑克牌)
        int j = i - 1;    // j 指向已排序部分的最后一个元素
        
        // 内层循环:从后向前扫描已排序部分,寻找 key 的正确插入位置
        // 如果已排序的元素比 key 大,就把它往后挪一位,腾出空间
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j]; 
            j--; 
        }
        
        // 找到正确位置后,将 key 插入(此时 j+1 就是空出来的位置)
        arr[j + 1] = key;
    }
}

// 打印数组的辅助函数
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {64, 34, 25, 12, 22};
    int n = sizeof(arr) / sizeof(arr[0]); // 计算数组长度
    
    printf("排序前:");
    printArray(arr, n);
    
    insertionSort(arr, n); // 调用插入排序
    
    printf("排序后:");
    printArray(arr, n);
    return 0;
}

示例演示

{64, 34, 25, 12, 22}

第 1 轮:处理元素 34

目标:将 34 插入到左侧已排序部分 {64} 的正确位置。

抽出 34(key = 34),左侧已排序部分为 {64}。

比较:34 < 64,所以 64 往后挪一位。数组变为:64, 64, 25, 12, 22

左侧已无元素,将 34 插入到最前面。

第 1 轮结束:34 归位。

当前数组:34, 64, \| 25, 12, 22 (竖线左边为已排好序的部分)
第 2 轮:处理元素 25

目标:将 25 插入到左侧已排序部分 {34, 64} 的正确位置。

抽出 25(key = 25),左侧已排序部分为 {34, 64}。

比较:25 < 64,64 往后挪。数组变为:34, 64, 64, 12, 22

继续比较:25 < 34,34 往后挪。数组变为:34, 34, 64, 12, 22

左侧已无元素,将 25 插入到最前面。

第 2 轮结束:25 归位。

当前数组:25, 34, 64, \| 12, 22
第 3 轮:处理元素 12

目标:将 12 插入到左侧已排序部分 {25, 34, 64} 的正确位置。

抽出 12(key = 12),左侧已排序部分为 {25, 34, 64}。

比较:12 < 64,64 往后挪。数组变为:25, 34, 64, 64, 22

继续比较:12 < 34,34 往后挪。数组变为:25, 34, 34, 64, 22

继续比较:12 < 25,25 往后挪。数组变为:25, 25, 34, 64, 22

左侧已无元素,将 12 插入到最前面。

第 3 轮结束:12 归位。

当前数组:12, 25, 34, 64, \| 22
第 4 轮:处理元素 22

目标:将 22 插入到左侧已排序部分 {12, 25, 34, 64} 的正确位置。

抽出 22(key = 22),左侧已排序部分为 {12, 25, 34, 64}。

比较:22 < 64,64 往后挪。数组变为:12, 25, 34, 64, 64

继续比较:22 < 34,34 往后挪。数组变为:12, 25, 34, 34, 64

继续比较:22 > 25 不成立(22 < 25),25 往后挪。数组变为:12, 25, 25, 34, 64

继续比较:22 > 12,停止挪动。将 22 插入到 12 的后面。

第 4 轮结束:排序完成。

最终结果:12, 22, 25, 34, 64

复杂度

时间复杂度是 \(O(n^2)\)(最坏和平均情况;若数组已有序,最好情况可降至 \(O(n)\)

空间复杂度是 \(O(1)\)(只需常数级的额外空间用于保存待插入元素 key)

相关推荐
gumichef1 小时前
排序专题(插入,)
数据结构·算法·排序算法
初学者,亦行者1 小时前
算法设计与分析3:贪心法 - 求解最短路径问题(TSP)
算法·代理模式
Starmoon_dhw1 小时前
题解:P16108 「o.OI R-1」基础博弈练习题
c++·算法·图论
大鱼>2 小时前
AI+快递分拣:视觉识别+自动分拣+异常检测
人工智能·深度学习·算法·机器学习
想要成为糕糕手2 小时前
238. 除了自身以外数组的乘积 — 面试向深度解析
javascript·算法·面试
浩瀚地学2 小时前
【面试算法笔记】0105-数组-螺旋矩阵
java·开发语言·笔记·算法·面试
Hesionberger2 小时前
动态规划与二分法破解最长递增子序列
java·数据结构·python·算法·leetcode
imuliuliang3 小时前
关于Kruskal 算法在图优化问题中的扩展应用7
算法
老约家的可汗3 小时前
Linux中基础IO
linux·服务器·算法