直接插入排序(C语言)-解析
直接插入排序:
输入: n 个数{ a1 , a2 , a3 , a4 , ……,aN }。
输出: 输入序列的一个排列(即重新排列){ a'1 , a'2 , a'3 ,……, a'N },使得 a'1≤a'2≤a'3≤……≤a'N。
首先,插入排序的工作机理与很多人打牌时,整理手中牌时的做法差不多。在开始摸牌时,我们的左手是空的,
牌面朝下放在桌上。接着,依次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张
牌的正确位置,要将它与手中已有的每一张从左到右地进行比较,如图 所示,无论什么时候,左手中的牌
都是排好序的,而这些牌都是原先在桌上那副牌里最先被拿起的最顶上面的一些牌。
由此看出,一趟直接插入排序的算法思想是: 每次将无序区的第一个记录按关键字插入到有序区的合适位置,并将有序区长度加1。
假如记录个数为8,输入关键字序列为(56,68,25,45,90,38,10,72),每次插入后的结果见下图。图中带括号“ [ ” " ] "的序列部分为妃递减序列,其余部分为
无序区。8 个记录的排序,经过 7 趟直接插入排序即可完成。
由图可见,第 i 趟插入排序若需将记录 a[i + 1] 插入到有序区 a[ 1.2...i] 中,插入前应先执行以下两步:
查找插入位置。从有序序列的位置 1 到 i ,依次判断是否为记录 a[ i + 1] 的插入位置 j,代码为:
1 | j = 0; do { j++; } while (a[j] < a[i+1]); |
2.移动记录空出插入位置。将有序区中从位置 i 到 j 的记录依次向后移动一个位置,空出插入位置 j ,代码为:
1 2 | key = a[i + 1]; //先将记录a[i + 1]保存在空闲的 0 号单元 k = i+1; do { k--; a[k+1] = a[k];} while ( k > j); |
若将判断插入位置的次序改为 i 到 1,则上述两步的代码合并为
1 2 3 | key = a[i+1]; j = i+1; do { j--; a[j+1] = a[j]; } while ( j > 1; && key < a[j -1];) |
具体代码(C语言):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include<stdio.h> int main() { int i,j,key; int a[10]; printf( "input 10 numberd :\n" ); //输入 for (i = 0;i < 10; i++) //数组 scanf( "%d" ,&a[i]); printf( "\n" ); for (i = 0; i < 10; i++) if (a[i + 1] < a[i]) //将a[i + 1]插入有序序列 { key = a[i + 1]; //先将a[i + 1]保存在关键字key中 j = i + 1; do { j--; a[j + 1] = a[j]; //记录后移 } while (key < a[j - 1]); //判断是否继续移动 a[j] = key; //插入 } printf( "the sorted numbers: \n" ); for (i = 0;i < 10; i++) //输出数组 printf( "%d " ,a[i]); printf( "\n" ); return 0; } |
输入/输出:
直接排序只需要一个记录的空间,其空间复杂度为O(1)。
最好情况下,待排记录有序,关键字比较次数为n - 1,移动记录为 0。
最坏情况下,待排记录逆序,时间复杂度为O(n2)。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?