从零学习直接插入排序

引言

在计算机科学领域,排序算法是数据结构和算法课程中非常重要的一部分。它们不仅帮助我们更好地理解和组织数据,而且在现实世界的应用中扮演着至关重要的角色,从数据库查询优化到搜索引擎结果的排序等。直接插入排序(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)以及对顺序存储和链表存储的兼容性,使得它在某些特定场景中仍然具有一定的应用价值。

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

相关推荐
jinmo_C++21 小时前
数据结构_ 二叉树线索化:从原理到手撕实现
数据结构
wdfk_prog21 小时前
[Linux]学习笔记系列 -- lib/sort.c 通用的排序库(Generic Sorting Library) 为内核提供标准的、高效的排序功能
linux·运维·c语言·笔记·stm32·学习·bug
shark_dev21 小时前
C/C++ 指针详解与各种指针定义
c语言·c++
钮钴禄·爱因斯晨1 天前
数据结构|图论:从数据结构到工程实践的核心引擎
c语言·数据结构·图论
yanqiaofanhua1 天前
C语言自学--自定义类型:结构体
c语言·开发语言·算法
向前阿、1 天前
数据结构从入门到实战————栈
c语言·开发语言·数据结构·程序人生
71-31 天前
C语言速成秘籍——循环结构(while、do while、for)和跳转语句(break,continue)
c语言·笔记·其他
洲覆1 天前
Redis 64字节分界线与跳表实现原理
数据结构·数据库·redis·缓存
im_AMBER1 天前
数据结构 02 线性表
数据结构·算法
-雷阵雨-1 天前
数据结构——包装类&&泛型
java·开发语言·数据结构·intellij-idea