从零学习直接插入排序

引言

在计算机科学领域,排序算法是数据结构和算法课程中非常重要的一部分。它们不仅帮助我们更好地理解和组织数据,而且在现实世界的应用中扮演着至关重要的角色,从数据库查询优化到搜索引擎结果的排序等。直接插入排序(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( <math xmlns="http://www.w3.org/1998/Math/MathML"> n 2 n^2 </math>n2)。

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

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

结语

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

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

相关推荐
钢琴上的汽车软件6 小时前
C 语言中const与指针:三种常见写法辨析
c语言·指针和const
ZK_H6 小时前
嵌入式c语言——关键字其6
c语言·开发语言·计算机网络·面试·职场和发展
澈2076 小时前
深入浅出C++滑动窗口算法:原理、实现与实战应用详解
数据结构·c++·算法
ambition202427 小时前
从暴力搜索到理论最优:一道任务调度问题的完整算法演进历程
c语言·数据结构·c++·算法·贪心算法·深度优先
cmpxr_7 小时前
【C】原码和补码以及环形坐标取模算法
c语言·开发语言·算法
代码旅人ing7 小时前
链表算法刷题指南
数据结构·算法·链表
yashuk8 小时前
C语言实现PAT练习及算法学习笔记,还有SQLite介绍
c语言·sqlite·开源项目·算法学习·pat练习
ACP广源盛139246256738 小时前
破局 Type‑C 切换器痛点@ACP#GSV6155+LH3828/GSV2221+LH3828 黄金方案
c语言·开发语言·网络·人工智能·嵌入式硬件·计算机外设·电脑
不爱吃炸鸡柳8 小时前
单链表专题(完整代码版)
数据结构·算法·链表
爱编码的小八嘎8 小时前
C语言完美演绎7-10
c语言