尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
数据结构:插入排序
排序所谓排序就是使一串记录按照其中的某个或某些关键字的大小递增或递减地排列起来的操作。关于数组排序的问题我们有很多种解决办法如冒泡排序、堆排序等。接下来我们将系统地了解并掌握几大排序算法的实现思路插入、选择、交换、归并排序有些排序算法我们会讲好几种实现方法。这些都是比较排序我们还将学习一种简单的非比较排序——计数排序。接下来让我们先进入插入排序的学习。插入排序直接插入排序直接插入排序是一种简单的插入排序法其基本思想是把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中直到所有的记录插入完毕为止得到一个新的有序序列。就像我们玩扑克牌一样每次抽到一张牌都会插入到我们当前的手牌中按顺序排列。思路我们以下面这个数组为例来讲解排序思路我们将3看作是一个有序数组然后1是待排序数据将1插入这个有序数组中。因为1比3小所以需要交换位置有序数组变为{1,3}我们再获取待排序数据2插入该有序数组中。2比3小则需要把3放到2的位置上该操作会覆盖2所以我们还需要把2存储起来。接下来2和1比较2比1大比较结束我们把2放到1后一个位置上。依次插入我们就可以排序好该数组了。从代码角度来说我们需要知道有序数组末尾位置end然后end1获取待排序数据再用tmp把该数据存储起来。如图所示我们先将3视作有序数组后面的就是待排序数据。我们用i来遍历数组。end先获取有序数组末尾位置iend1获取的就是待排序数据1的位置tmp存储起来。然后tmp跟end处数据比较1比3小将end处数据放到end1处。然后end- -end来到了-1越界了此时结束比较将tmp放到end1的位置处。第一个数据插入结束i此时i1endi1end1就是待排序数据的位置tmp存储该数据。tmp和end处数据比较2比3小把end处数据放到end1处然后end- -。再将end和tmp比较2比1大不用将end处数据放到end1处比较结束将tmp放到end1处这个数据插入也完成了。接下来继续iendiend1获取下个排序数据循环插入直到排序完为止。代码实现综上所述我们需要一个for 循环 i来遍历整个数组因为获取的i是有序数组末尾下标end一开始i 0每次循环后有序数组元素个数都会1。循环就可以获取到end。后面我们还要通过end1获取待排序数据所以循环条件为i n - 1。然后我们初始化一下end 和待排序数据。接下来我们要插入待排序数据tmp需要从后往前与有序数组中的数据进行比较根据思路我们是让end- -来从后往前拿到有序数组中的数据的所以循环条件为end ≥ 0。我们将tmp和end处的数据进行比较如果tmp小于arr[end]则说明要把end处数据放到end1相当于往后挪然后end- -进入下次循环。直到end0自动跳出循环arr[end1]tmp此次插入数据结束如果tmp大于arr[end]则说明不用往后挪元素了break跳出循环然后arr[end1]tmp相当于自己给自己赋值。这个代码也就完成了。我们测试一下结果符合预期说明代码逻辑没什么问题。时间复杂度评估外层我们写了一个for循环循环n-1次内部嵌套了一个while循环在最坏情况下时间复杂度为O(n)。最坏情况也就是一个降序数组每次排序数据的移动都达到了最大值也就是大的数据在前小的数据在后。如果我们可以尽量让小的数据在前大的数据在后那么每次排序数据的移动量会尽可能减小时间复杂度就会接近O(n)。既然如此我们可不可以给原数组进行预排序让小的数据在前大的数据在后呢答案是可以的希尔排序因此诞生了。希尔排序希尔排序法又称缩小增量法。希尔排序法的基本思想是先选定一个整数通常是 gap n/3 1把待排序文件所有记录分成各组所有的距离相等的记录分在同一组内并对每一组内的记录进行排序然后 gap gap/3 1 得到下一个整数再将数组分成各组进行插入排序当 gap 1 时就相当于直接插入排序。思路比如说有以下数组一开始 gap4每隔 gap 个位置的数据分为一组。每组就是 {5,6,4}, {2,9}, {3,8}, {7,1}。然后我们对每组都进行预排序将小的数据放前大的数据放后面。每组就变成 {4,5,6}, {2,9}, {3,8}, {1,7} 了。然后 gapgap/312再进行分组。这次分为了两组{4,3,5,8,6}, {2,1,9,7}。再次给每组进行预排序。然后gapgap/311gap1时相当于直接插入排序。此时排序就排序好了。这就是希尔排序的整个过程。我们代码思路简单过一遍一开始gap4我们用i来遍历整个数组我们是一整组排完再排下一组吗不是我们是i直接遍历一遍数组。一开始i0endiendgap就可以获取该组待排序数据。同样地需要tmp来存储。6比5大不用挪数据此次插入结束。i拿到下一个组的有序数组末尾endiendgap拿到该组待排序数据tmp存储。9比2大不用挪数据此次插入结束。i拿到下一个组的有序数组末尾endiendgap拿到该组待排序数据tmp存储。8比3大不用挪数据此次插入结束。i拿到下一个组的有序数组末尾endiendgap拿到该组待排序数据tmp存储。1比7小end放到endgap的位置处然后end-gap获取有序数组前面的数据。此时发现end越界了说明该组前面没有数据比较结束tmp放到endgap的位置处。此次插入结束i拿到下一个组的有序数组末尾endiendgap拿到该组待排序数据tmp存储。4比6小将end放到endgap的位置处end-gap拿到有序数组前一个数据。4比5小end放到endgap的位置处end-gap拿到有序数组前一个数据。end越界说明该组前面没有数据了比较结束将tmp放到endgap的位置处。此次插入结束i拿到下一个组的有序数组末尾endiendgap拿到该组待排序数据tmp存储。发现endgap越界了说明本次预排序结束。下次gapgap/31继续预排序直到gap1时变成直接插入排序。我们会发现用i遍历当i0时排序第一组的一个数据i1时可能就排的是第二组的一个数据了说明用i来遍历可以实现该功能并且排序的循环条件应该是in-gap。然后和直接插入排序不同的是每次end是end-gap获取该组前一个数据。其他基本一样。代码实现我们先让 gapn然后每次进入预排序 gapgap/31开始预排序。这里循环条件为 gap 1 的原因是gap 到最后一定是 1gapgap/31如果循环条件改为 gap 0 的话会进入死循环。然后我们开始写预排序的代码逻辑实际上和直接插入排序没什么区别只是在细微处做了一些改动。代码就完成了我们来测试一下。结果符合预期说明代码逻辑没有问题。时间复杂度评估希尔排序不是嵌套了三层循环吗为什么时间效率比直接插入排序好我们简单来看一下随机生成10万个数据然后让这两个算法来排序看哪个算法用时更少。voidtest(){srand(time(NULL));//开辟10万个整型空间int*a1(int*)malloc(100000*sizeof(int));if(a1NULL){perror(malloc);exit(-1);}int*a2(int*)malloc(100000*sizeof(int));if(a2NULL){perror(malloc);exit(-1);}//随机生成10万个数for(inti0;i100000;i){a1[i]rand();a2[i]a1[i];}//排序并计时intbegin1clock();SelectSort(a1,100000);intend1clock();intbegin2clock();ShellSort(a1,100000);intend2clock();printf(SelectSort:%d\n,end1-begin1);printf(ShellSort:%d\n,end2-begin2);}我们可以发现希尔排序比直接插入排序快了 2000 多倍也就是几毫秒的时间就排好了 10 万个数据。对于希尔排序的时间复杂度和 gap 值的选取还有初始数据的有序程度有关平均情况下希尔排序的时间复杂度为 O(n^1.3) ~ O(nlogn) 之间比直接插入排序要快得多。
RELATED

相关推荐

大模型技术面试全攻略:理论与工程实践

大模型技术面试全攻略:理论与工程实践

1. 大模型技术面试的时代背景与核心价值2026年的技术招聘市场正在经历一场深刻变革。根据多家头部科技企业的招聘数据,大模型相关岗位的面试通过率从2023年的18%骤降至2026年的6.7%,而岗位需求量却同比增长了320%。这种"高需求、高门槛"的现状…

📅 2026/11/1 4:45:44
企业招聘风险防控与科学评估体系构建

企业招聘风险防控与科学评估体系构建

1. 招聘困境的本质剖析在人力资源领域摸爬滚打十几年,我发现一个令人深思的现象:超过60%的企业在入职半年内就发现新员工与岗位要求存在明显偏差。某科技公司HR总监曾向我透露,他们每年因招聘失误导致的重置成本高达年度人力预算的15%。这种&…

📅 2026/10/18 16:35:27
构建合成人评测框架:LLM Agent隐私、记忆与工具能力评估实战

构建合成人评测框架:LLM Agent隐私、记忆与工具能力评估实战

1. 项目概述:为什么我们需要一个“合成人”的测试场?最近在折腾大语言模型智能体(LLM Agent)的评测时,我遇到了一个挺头疼的问题。你想,一个智能体要真正“有用”,它得能处理复杂的、涉及个人隐…

📅 2026/10/7 5:08:11
MORE NEWS

更多资讯

📰

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

📰

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

📰

先能用,再好用:从烂尾复盘到两周上线,全栈项目的‘原型—快速迭代‘方法论

先能用,再好用:从烂尾复盘到两周上线,全栈项目的“原型—快速迭代”方法论 全栈学习路径的文章已经很多了:怎么选技术栈、怎么搭环境、怎么记文档,几乎每个方向都有人写。但一个更扎心的问题很少有人正面讨论——为什…

📰

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看‘会思考‘改写了哪些边界

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看“会思考”改写了哪些边界 一、先说结论:变强的不是“知识”,而是“解法” 每次新模型发布,评测榜单都会涨几个点,大…

📰

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

📰

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬