数据结构----插入排序

一、基本思想

插入排序的核心思想:把数组分为「有序区」和「无序区」。初始状态:

第 1 个元素天然为有序区;

后面所有元素为无序区。

每一趟排序:从无序区取出第一个元素,向前扫描有序区,按照大小顺序,插入到有序区的合适位置;重复操作,直到整个数组全部转为有序区。特点:逐个插入、逐步有序,稳定排序、就地排序。


二、直接插入排序

  1. 算法原理

数组下标从 i = 1 开始(默认 a [0] 有序);

暂存当前待插入元素 temp = a[i];

从有序区末尾 j = i-1 向前遍历;

若 a[j] > temp,向后移位腾出空位;

直到找到比 temp 小的位置,将 temp 插入;

i++,进入下一趟。

  1. 完整代码
复制代码
  1. void InsertSort(int a[], int n)

  2. {

  3. int i, j, temp;

  4. for(i = 1; i < n; i++)

  5. {

  6. temp = a[i]; // 待插入元素

  7. // 向前移位

  8. for(j = i - 1; j >= 0 && a[j] > temp; j--)

  9. {

  10. a[j + 1] = a[j];

  11. }

  12. a[j + 1] = temp; // 插入正确位置

  13. }

  14. }

  15. 性能分析

最好情况(数组已有序):O(n)

最坏 / 平均情况:O(n 2 )

空间复杂度:O(1) 原地排序

稳定性:稳定(相等元素不交换相对位置)


三、折半插入排序(二分插入排序)

  1. 改进思路

直接插入排序中,向前查找插入位置是顺序查找效率低;利用有序区已有序,改用折半查找快速定位插入点,减少比较次数。 仅减少比较次数,元素移动次数不变。

  1. 核心流程

折半查找,快速确定待插入位置 low;

将插入位置后所有元素统一后移;

放入待插入元素。

  1. 性能

比较次数:O(nlog 2 n)

移动次数:仍为 O(n 2 )

整体时间复杂度:O(n 2)稳定、原地排序


四、希尔排序(缩小增量插入排序)

  1. 改进思想

直接插入在数据逆序、乱序时效率极差;希尔排序:分组 + 远距离插入先取较大增量,将数组分组,组内直接插入排序;逐步缩小增量,直至增量为 1,退化为普通插入排序。

  1. 原理

设定增量 d,按下标间隔 d 分组;每组内部做直接插入排序;不断缩小 d,重复分组排序;d=1 整体有序。

  1. 关键性质

时间复杂度:约 O(n 1.3 )

稳定性:不稳定(远距离交换会打乱相等元素顺序)

属于插入类排序,是直接插入的优化版本


五、插入排序共同特点总结

算法逻辑简单,易于理解、代码短;

适合数据量小、基本接近有序的序列;

直接插入、折半插入:稳定;希尔排序:不稳定;

都是就地排序,额外空间仅常数级;

数据越有序,插入排序越快。

相关推荐
im_AMBER1 小时前
Leetcode 162 除了自身以外数组的乘积 | 接雨水
开发语言·javascript·数据结构·算法·leetcode
Westward-sun.1 小时前
YOLO目标检测算法与mAP评估指标详解(附示例)
算法·yolo·目标检测
cpp_25011 小时前
P1873 [COCI 2011/2012 #5] EKO / 砍树
数据结构·c++·算法·题解·二分答案·洛谷·csp
啊哦呃咦唔鱼1 小时前
leetcodehot100-347. 前 K 个高频元素
数据结构·算法·leetcode
玛丽莲茼蒿1 小时前
Leetcode hot100 多数元素【简单】
算法·leetcode·职场和发展
AbandonForce1 小时前
Map类:pair键值对|map的基本操作|operator[]
开发语言·c++·算法·leetcode
澈2071 小时前
C++核心:封装与static静态成员实战指南
开发语言·c++·算法
田梓燊1 小时前
力扣:146.LRU 缓存
算法·leetcode·缓存
_深海凉_1 小时前
LeetCode热题100-杨辉三角
算法·leetcode·职场和发展