首页 / 财经 / 股票 / 正文

插入排序(算法排序之插入排序实现)

放大字体  缩小字体 来源:儿童写字台 2026-04-17 17:24  浏览次数:4

一、算法概述

插入排序是一种简单直观的排序算法,其核心思想是 将待排序元素逐个插入到已排序序列的适当位置,从而构建完整的有序序列 。该算法类似于玩扑克牌时整理手牌的过程。


算法排序之插入排序实现nerror="javascript:errorimg.call(this);">

插入排序的核心逻辑,就和我们整理手中的扑克牌如出一辙。

开局摸牌时,左手先攥住第一张牌,它天然有序。后续每摸一张新牌,就从右往左和左手里的牌逐一比对,把它插入到比它小的牌右边、比它大的牌左边的位置。重复这个动作,直到所有牌都被插入左手,最终就能得到一副有序的牌。

对应到算法中,数组的第一个元素就是 “初始手牌”,从第二个元素开始,逐个将元素插入前面已排序的区间,最终实现整体有序。

二、核心实现步骤

1. 区间划分

  • 将数组分为两个逻辑区间:
    • 已排序区间 :初始为 [0, 0] (单个元素默认有序)
    • 未排序区间 :初始为 [1, n-1] (n为数组长度)
  • 变量 i 作为 未排序区间的起始索引

2. 外层循环:遍历未排序元素

for (int i = 1; i < arr.length; i++) {    // 插入排序逻辑}
  • 从下标1开始遍历,共执行 n-1 次
  • 每次处理一个未排序元素,将其插入到已排序区间的合适位置

3. 保存待插入元素

int tmp = arr[i];
  • 将要插入的元素值保存到临时变量 tmp
  • 避免在后续移动元素时被覆盖

4. 内层循环:寻找插入位置

int j = i;while (j > 0 && tmp < arr[j - 1]) {    arr[j] = arr[j - 1];    j--;}
  • 从当前位置 i 开始向左比较
  • 条件 j > 0 确保不越界
  • 条件 tmp < arr[j - 1] 寻找比 tmp 小的元素
  • 元素后移 :将比 tmp 大的元素向右移动一位,为插入腾出空间

5. 执行插入操作

if (j != i) {    arr[j] = tmp;}
  • 只有当位置发生变化( j != i )时才执行插入
  • 将 tmp 插入到找到的合适位置 j
  • 插入后,已排序区间长度加1

三、排序过程示例

以数组 {11, 3, 5, 2, 13} 为例,排序过程如下:

初始状态

  • 已排序区间: [11]
  • 未排序区间: [3, 5, 2, 13]

第1轮(i=1,tmp=3)

  1. j=1 ,比较 3 < 11 ,成立
  2. 元素后移: arr[1] = arr[0] → 数组变为 [11, 11, 5, 2, 13]
  3. j-- → j=0 ,循环结束
  4. 插入 tmp : arr[0] = 3 → 数组变为 [3, 11, 5, 2, 13]
  5. 已排序区间: [3, 11]

第2轮(i=2,tmp=5)

  1. j=2 ,比较 5 < 11 ,成立
  2. 元素后移: arr[2] = arr[1] → 数组变为 [3, 11, 11, 2, 13]
  3. j-- → j=1 ,比较 5 < 3 ,不成立,循环结束
  4. 插入 tmp : arr[1] = 5 → 数组变为 [3, 5, 11, 2, 13]
  5. 已排序区间: [3, 5, 11]

第3轮(i=3,tmp=2)

  1. j=3 ,比较 2 < 11 ,成立
  2. 元素后移: arr[3] = arr[2] → 数组变为 [3, 5, 11, 11, 13]
  3. j-- → j=2 ,比较 2 < 5 ,成立
  4. 元素后移: arr[2] = arr[1] → 数组变为 [3, 5, 5, 11, 13]
  5. j-- → j=1 ,比较 2 < 3 ,成立
  6. 元素后移: arr[1] = arr[0] → 数组变为 [3, 3, 5, 11, 13]
  7. j-- → j=0 ,循环结束
  8. 插入 tmp : arr[0] = 2 → 数组变为 [2, 3, 5, 11, 13]
  9. 已排序区间: [2, 3, 5, 11]

第4轮(i=4,tmp=13)

  1. j=4 ,比较 13 < 11 ,不成立,循环结束
  2. j == i ,无需插入
  3. 数组保持 [2, 3, 5, 11, 13]
  4. 已排序区间: [2, 3, 5, 11, 13]

四、算法特点

时间复杂度

  • 最佳情况 :O(n)(数组已完全有序,内层循环无需执行)
  • 最坏情况 :O(n²)(数组完全逆序,每个元素都需移动到最前面)
  • 平均情况 :O(n²)

空间复杂度

  • O(1) :原地排序,仅使用常数级额外空间

稳定性

  • 稳定排序 :相同元素的相对位置不会改变

插入排序的优势

  • 对于 近乎有序的数组 ,效率很高(接近O(n))
  • 对于 小规模数据 ,性能表现良好
  • 空间复杂度低 ,适合内存受限场景
  • 实现简单 ,代码易于理解和维护

五、代码优化点

1. 避免不必要的赋值

if (j != i) {    arr[j] = tmp;}
  • 当元素已经在正确位置时,避免重复赋值
  • 减少了无效的写操作,提高效率

2. 边界条件处理

  • 外层循环从 i=1 开始,避免了对单个元素的无效处理
  • while循环条件 j > 0 确保数组不越界

3. 清晰的变量命名

  • tmp :明确表示要插入的临时元素
  • i 和 j :分别表示未排序区间起始和插入位置
  • 代码可读性强,易于理解

六、与选择排序的对比

特性 插入排序 选择排序 时间复杂度(最佳) O(n) O(n²) 时间复杂度(最坏) O(n²) O(n²) 空间复杂度 O(1) O(1) 稳定性 稳定 不稳定 适用场景 近乎有序数据、小规模数据 小规模数据 核心思想 逐个插入构建有序序列 选择最小元素交换到已排序末尾

七、总结

插入排序是一种高效的基础排序算法,尤其适合处理近乎有序或小规模的数据。其核心思想是通过将元素逐个插入到已排序序列的适当位置,逐步构建完整的有序序列。该算法实现简单,空间复杂度低,是学习排序算法的重要基础。

通过分析给定代码,可以清晰地理解插入排序的工作原理:从第二个元素开始,每次将当前元素插入到左侧已排序序列的合适位置,直到所有元素排序完成。这种"增量构建"的思路

打赏
0相关评论
热门搜索排行
精彩图片
友情链接
声明:本站信息均由用户注册后自行发布,本站不承担任何法律责任。如有侵权请告知立立即做删除处理。
违法不良信息举报邮箱:115904045
头条快讯网 版权所有
中国互联网举报中心