从零学习直接插入排序

引言

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

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

相关推荐
大龄Python青年1 小时前
C语言 交换算法之加减法,及溢出防范
c语言·开发语言·算法
朱剑君2 小时前
排序算法——基数排序
算法·排序算法
谷雪_6582 小时前
鼠标交互初体验:点击屏幕生成彩色气泡(EGE 库基础)
c语言·开发语言·microsoft·交互
yzlAurora3 小时前
删除链表倒数第N个节点
数据结构·链表
进击的小白菜3 小时前
如何高效实现「LeetCode25. K 个一组翻转链表」?Java 详细解决方案
java·数据结构·leetcode·链表
拾忆-eleven3 小时前
C++算法(19):整数类型极值,从INT_MIN原理到跨平台开发实战
数据结构·c++·算法
我是一只鱼02235 小时前
LeetCode算法题 (反转链表)Day17!!!C/C++
数据结构·c++·算法·leetcode·链表
喜欢吃燃面6 小时前
C++:扫雷游戏
c语言·c++·学习
小郝 小郝7 小时前
【C语言】五一回归,复习动脑
c语言·开发语言
ice___Cpu8 小时前
数据结构 - 10( B- 树 && B+ 树 && B* 树 4000 字详解 )
数据结构