【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)

目录

[一、插入排序 算法思想](#一、插入排序 算法思想)

[二、插入排序 算法步骤](#二、插入排序 算法步骤)

四、复杂度分析

时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性:稳定算法

五、应用场景


💓 博客主页:C-SDN花园GGbond

⏩ 文章专栏:探索数据结构与算法

一、插入排序 算法思想

**插入排序(Insert Sort)**是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。它的思想类似于我们打扑克牌时的整理

二、插入排序 算法步骤

  1. 将第一待排序 序列的第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

  2. 从尾到头依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

  3. 具体步骤是这样的:

    (以排升序为例)

    从第一个元素开始,该元素可以认为已经被排序。
    取出下一个元素,在已经排序的元素序列中从后向前扫描。
    如果该元素(已排序)大于新元素,将该元素向后移动一位。
    重复步骤3,直到找到已排序的元素小于或者等于新元素的位置。
    将新元素插入到该位置后。
    重复步骤2~5,直到所有元素都排序完成。

动图

三、C语言代码实现

cpp 复制代码
//插入排序
void InsertSort(int* a, int len)
{
	//0到end有序,插入a[end+1]
	for (int i = 0; i < len - 1; i++)
	{
		int end = i;
		int tmp = a[i + 1];
		while (end >= 0)
		{
			if (a[end]>tmp)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}

		}
		a[end + 1] = tmp;
	}
}

四、复杂度分析

时间复杂度:O(n^2)

最好情况(O(n)):

当输入数组已经是排序状态时,插入排序的性能最优。此时,每个元素只需与其前面的一个元素进行比较(因为它已经位于正确的位置),因此总共需要进行大约n-1次比较,时间复杂度为O(n)。这里的n是数组的长度。

最坏情况(O(n^2)):

当输入数组完全逆序时,插入排序的性能最差。对于每个元素,都需要与其前面的所有元素进行比较,直到找到合适的位置。因此,第i个元素需要比较i次(其中i从2开始,直到n),总共需要进行的比较次数大约为1 + 2 + 3 + ... + (n-1) = n(n-1)/2,时间复杂度为O(n^2)。

平均情况(O(n^2)):

对于随机排列的数组,插入排序的平均时间复杂度也是O(n^2)。这是因为大部分情况下,元素都需要进行多次移动和比较才能找到正确的位置。

空间复杂度:O(1)

插入排序是一种原地排序算法,它只需要一个额外的存储空间来暂存当前需要插入的元素(即"key"),而不需要额外的数组来存储排序过程中的数据。因此,其空间复杂度为O(1)。

稳定性:稳定算法

插入排序是一种稳定的排序算法。在插入排序过程中,如果两个相等的元素,后面的元素不会移动到前面元素的前面,而是直接插入到与它相等的元素之后,从而保持了原有的相对顺序。

五、应用场景

插入排序虽然在大规模数据集上可能不是最高效的排序算法,但其简单性、稳定性和在某些特定场景下的高效性使得它在许多实际应用中仍然具有一定的价值。

小规模数据集:由于插入排序在小规模数据集上表现良好,且实现简单,因此常用于对少量数据进行排序的场景。快速排序的小区间优化

几乎有序的数据集:当数据已经接近有序时,插入排序的性能会显著提高。因为此时大部分元素已经处于或接近其最终位置,所需的比较和移动次数会大幅减少。

链表排序:由于链表不支持像数组那样的随机访问,因此在链表上进行排序时,插入排序成为了一个非常合适的选择。它可以通过改变节点的指针来实现元素的移动,而不需要额外的存储空间。

相关推荐
dialect_7 小时前
KMP算法
开发语言·c++·算法
总要学点什么8 小时前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
漂流瓶jz8 小时前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
开开心心_Every9 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
chenbingjie_c10 小时前
C++ 多态完全指南:从虚函数重写到虚函数表原理
开发语言·c++
吴卫斌10 小时前
定投ETF实战指南(四):行业/主题ETF——定投的“进攻端“
开发语言·python·股票·量化
·present·10 小时前
CSAPP(Bomb lab)
c语言·c++
超级架构师11 小时前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
叼烟扛炮11 小时前
Linux 学习笔记(四十三):网络编程进阶——自定义协议解决 TCP 粘包与守护进程
linux·开发语言·网络·笔记·tcp/ip
LMT流氓兔12 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节