从零学习直接插入排序

引言

在计算机科学领域,排序算法是数据结构和算法课程中非常重要的一部分。它们不仅帮助我们更好地理解和组织数据,而且在现实世界的应用中扮演着至关重要的角色,从数据库查询优化到搜索引擎结果的排序等。直接插入排序(Straight Insertion Sort)是一种简单直观的排序算法,虽然它不是最有效的算法之一,特别是在处理大规模数据时,但其易于理解的特点使其成为初学者学习排序概念的理想选择。本文将深入探讨直接插入排序的工作原理、实现方式以及它的优缺点。

正文

直接插入排序的基本思想是将数组分为两部分:已排序部分和未排序部分(见下图),每次从未排序部分取出第一个元素,在已排序的部分中找到适当的位置并插入。该过程类似于打扑克牌时整理手牌的过程:从一副乱序的牌中依次抽取一张,并将其正确地插入手中已经排好序的牌中。

具体步骤如下:

  1. 从数组的第二个元素开始(假设第一个元素已经是有序的),将当前元素作为"关键元素"。
  2. 将关键元素与其之前的所有元素进行比较。如果关键元素小于前一个元素,则交换两者的位置;否则,停止比较。
  3. 对剩余的未排序部分重复上述步骤,直到整个数组排序完成。

代码见下:

css 复制代码
void InsertSort(ElemType A[],int n){
	int i,j;
	for(i=2;i<=n;i++){
		if(A[i]<A[i-1]){
			A[0]=A[i];
			for(j=i-1;A[0]<A[j];--j)
				A[j+1]=A[j];
			A[j+1]=A[0];
		}		
	}
} 

演示动画见下:

根据上述分析可知,仅使用常数个辅助单元,因而空间复杂度为O(1);

在最好情况下的比较次数为n-1,此时的移动次数为0;在最坏情况下的比较次数为(n-1)n/2,此时总的移动次数也达到最大;此时取上述最好情况和最坏情况的平均值作为平均时间复杂度,即O( n 2 n^2 n2)。

由于每次插入的元素都是从后往前移的,所以不会出现相同元素相对位置发生改变的情况(即不会出现下图所示情况),因而该算法是一个稳定的排序算法。

该算法在访问元素时是依次访问的,因而既可使用顺序存储也可使用链表存储。

结语

直接插入排序作为一种简单而经典的排序算法,为初学者提供了一个直观理解排序过程的切入点。它通过模拟日常生活中整理物品的方式,清晰地展示了如何将无序数据逐步转化为有序数据。尽管其时间复杂度在最坏情况下达到 O( n 2 n^2 n2),使其在处理大规模数据时效率较低,但其稳定性、低空间复杂度O(1)以及对顺序存储和链表存储的兼容性,使得它在某些特定场景中仍然具有一定的应用价值。

对于小规模数据或接近有序的数据集,直接插入排序表现出较高的效率,因此在实际开发中,它可以作为快速实现和验证排序逻辑的一种选择。此外,该算法的思想也为更复杂的排序算法提供了基础。

相关推荐
三品吉他手会点灯16 小时前
C语言学习笔记 - 50.流程控制4 - 流程控制为什么非常非常重要
c语言·开发语言·笔记·学习
JAVA面经实录91717 小时前
Java 数据结构与算法 (终极完整学习文档)
java·数据结构·算法
影视飓风TIM19 小时前
数据结构 | 链表超全笔记(单链表+双链表+高频算法题)
数据结构·笔记·链表
十月的皮皮20 小时前
C语言学习笔记20260615-有序升序序列合并
c语言·笔记·学习
牛油果子哥q20 小时前
STL set与map底层精讲,红黑树适配原理、有序去重特性、迭代器遍历、API实战与面试核心考点全解
开发语言·数据结构·c++·面试
一切皆是因缘际会1 天前
LLM轻量化联邦微调机理
数据结构·人工智能·数学建模·ai
玖玥拾1 天前
C/C++ 数据结构(六)链表迭代器与底层
c语言·数据结构·c++·链表·stl库
牛油果子哥q1 天前
AVL平衡树与红黑树深度精讲对比,平衡因子、四大旋转原理、着色规则、平衡策略、性能差异与面试手撕全解
数据结构·c++·面试
Seraphina_Lily1 天前
深入C语言底层:隐式类型转换、整数提升与截断的“致命”陷阱
c语言·开发语言·算法
C++ 老炮儿的技术栈1 天前
Ubuntu root账号自动登陆
linux·运维·服务器·c语言·c++·ubuntu·visual studio