当前位置: 首页 > news >正文

【初阶数据结构】 升沉有序的平仄 排序

点击展开/收起 文章目录文章目录排序分类1. 插入排序直接插入排序希尔排序2. 选择排序选择排序堆排序3. 归并排序归并排序递归实现归并排序的非递归实现希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力在学习编程中,把无序的东西变的有序在生活中很常见,排序算法的复杂度对我们算法优劣还是有很大的影响进入排序讲解之前我要教大家写测试用例,来测试我们写的排序的快慢分为四步走:在堆上创建N个数据的空间种时间种子,用循环将生成的随机数,加入到开辟的空间中去利用time.h里面的begin(),end()函数,记录当前的时间,和程序结束的时间,然后相减,得到程序运行的时间释放开辟的空间,防止内存泄漏voidTestOP(){intN100000;srand((unsignedint)time(0));int*a1(int*)malloc(sizeof(int)*N);int*a2(int*)malloc(sizeof(int)*N);for(inti0;iN;i){a1[i]rand()i;//a1[i] rand();a2[i]a1[i];}intbegin1clock();InsertSort(a1,N);intend1clock();intbegin2clock();ShellSort(a2,N);intend2clock();printf(InsertSort:%d\n,end1-begin1);printf(ShellSort: %d\n,end2-begin2);free(a1);free(a2);}排序分类以下是我要讲的全部排序,当然这一次性肯定讲不完,我会看情况分为两次或者三次讲完1. 插入排序直接插入排序图是很清楚默认排的是升序,遇到小的就往前插入,直到遇到,比自己小的停止,这种效率还是很高的,时间复杂度虽然是O(N^2) , 但出现O(N^2), 情况还是比较难,要求是高度升序才有可能,所以作为O(N^2)的排序方式还是比较快的.以下是代码实现演示过程voidInsertSort(int*a,intn){for(intj0;jn-1;j){intendj;inttmpa[end1];while(end0){if(a[end]tmp){a[end1]a[end];end--;}else{break;}a[end1]tmp;}}}希尔排序希尔排序时间复杂度为O(N^1.3),不用掌握计算,因为需要很多数学的专业知识从上面看出其实选择排序这个结构还是很不错的一个结构,我们能不能改进一下结构,让他的排序速度变快呢?我们可以看出与插入排序对比,希尔排序多了一个gap组gap的选取,有大量验证,gap/3得到的排序速度最快,gap/31是为了保证gap不为零,gap既是组数又是一次跳的步数,gap是干什么用的呢?gap是用来把我们的数据分割成gap组分别进行直接插入排序如图所示第二个循环的过程,随i变化,分别开始,进行直接插入排序,那结束条件是什么?第二个循环的结束条件最外层调整gap使得gap等于1时最后一次排序voidShellSort(int*a,intn){intgapn;while(gap1){gapgap/31;for(inti0;in-gap;i){intendi;inttmpa[endgap];while(end0){//类比直接插入排序,把1换成gapif(a[end]tmp){//这里间隔是gap所有加减都gapa[endgap]a[end];end-gap;}elsebreak;a[endgap]tmp;}}}}对比一下1000000个数据下,直接插入排序和希尔排序的速度可以看出差距还是挺大的2. 选择排序选择排序这里逻辑很简单,就是每轮遍历,选出最大最小的,放在begin和last位置处**注意:**这里当begin与max相重合时,Swap(a[begin], a[min]);后a[max]被交换到a[min]的位置要更新max位置voidSelectSort(int*a,intn){intbegin,last,min,max;;begin0;lastn-1;while(beginlast){minmaxbegin;for(intibegin1;ilast;i){if(a[i]a[max]){maxi;}if(a[i]a[min]){mini;}}Swap(a[begin],a[min]);if(maxbegin)//坑点,如果相等要进行更新max{minmax;}Swap(a[last],a[max]);begin;last--;}}堆排序我这里演示的是建大堆排升序思路是每次把最大的数据堆顶数据与堆的最后一个数据交换位置,size- -;再重新找次大的数据,再重复此过程下面演示堆的建堆过程还有排序过程voidHeapDown(int*a,intsize,intparent){intchild2*parent1;while(childsize){if(child1sizea[child1]a[child]){child;}if(a[parent]a[child]){Swap(a[parent],a[child]);parentchild;child2*parent1;}else{break;}}}voidHeapSort(int*a,intsize){for(intisize;i1;i--){Swap(a[0],a[i-1]);HeapDown(a,i-1,0);}}堆排序与选择排序对比100000,由于选择排序太慢,这里就用十万个数据由此看出直接插入排序还是比选择排序快很多的3. 归并排序归并排序递归实现归并是一种分而治之的思想,先分成小组,单个的,再进行顺序归并再这里最坏分割时间复杂度是O(logN)注意这里在分割区间时的小细节问题void_Mergesort(int*a,int*tmp,intbegin,intend){if(beginend)return;else{intmid(beginend)/2;//beginend返回这里往下走,进行有序合并,就像顺序表篇讲的合并有序数组_Mergesort(a,tmp,begin,mid);_Mergesort(a,tmp,mid1,end);intbegin1begin;intend1mid;intbegin2mid1;intend2end;inti0;while(begin1end1begin2end2){//有序合并if(a[begin1]a[begin2]){tmp[i]a[begin1];}else{tmp[i]a[begin2];}}//有一组有剩余,拷贝到tmp中去while(begin1end1){tmp[i]a[begin1];}while(begin2end2){tmp[i]a[begin2];}//注意着里要从begin开始拷贝,拷贝回a中//拷贝回去是从a[begin]拷,对于最左边begin0,但对于其他的递归分割的begin却不是0memcpy(abegin,tmp,sizeof(int)*(end-begin1));}}voidMergesort(int*a,intn){int*tmp(int*)malloc(sizeof(int)*n);if(tmpNULL){perror(malloc fail);return;}_Mergesort(a,tmp,0,n-1);free(tmp);tmpNULL;}归并排序的非递归实现非递归实现的大坑:就是数据不是整数gap倍,时的归并;归并会出现访问越界的情况我们来仔细分析以下的越界情况:三种越界情况展示:在这里我们可以归纳一下越界逻辑你会发现,end1越界,和end1,begin2越界其实是一种情况,第二区间不存在都表示后面没有数了不用归并了// 边界修正 if (end1 n|| begin2 n) { end1 n - 1;不归并,直接把尾区间给end1;往下走 break; // 第二区间不存在跳过 } if (end2 n) end2 n - 1;第二区间还有数继续归并void_Mergesort2(int*a,int*tmp,intbegin,intend){intnend-begin1;// 总元素个数intgap1;while(gapn)// 改用 n更清晰{for(inti0;in;i2*gap){intbegin1i;intend1igap-1;intbegin2igap;intend2i2*gap-1;// 边界修正if(end1n)end1n-1;if(begin2n)break;// 第二区间不存在跳过if(end2n)end2n-1;intleftbegin1;// 保存原始左边界intji;// tmp 中的起始索引while(begin1end1begin2end2){if(a[begin1]a[begin2])tmp[j]a[begin1];elsetmp[j]a[begin2];}while(begin1end1)tmp[j]a[begin1];while(begin2end2)tmp[j]a[begin2];// 正确拷贝从 left 位置开始长度为 j - leftmemcpy(aleft,tmpleft,sizeof(int)*(j-left));}gap*2;}}//非递归实现归并voidMergesort2(int*a,intn){int*tmp(int*)malloc(sizeof(int)*n);if(tmpNULL){perror(malloc fail);return;}_Mergesort2(a,tmp,0,n-1);free(tmp);tmpNULL;}希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力
http://www.zskr.cn/news/1309814.html

相关文章:

  • 工业 DC-DC 封装与性能解析,钡特电源 DB2-05D15XT 与金升阳 A0515XT-2WR3 为工业标准模块电源
  • 对比直接使用官方API,Taotoken在用量可视性与账单追溯上的优势
  • 2026年5月市政水务4-20mA电磁流量计国产厂家排名 - 水质仪表品牌排行榜
  • 2026杭州玻尿酸产品:下巴、面颊、颞部等部位的产品搭配方案 - charlieruizvin
  • 做了5年电力运维,教你挑靠谱无人机电力巡检公司 - 速递信息
  • 泉州黄金回收哪家靠谱?2026丰泽/鲤城/晋江实体门店盘点,上门回收当场结算 - 润富黄金珠宝行
  • 车载5G/V2X模组TOP10榜单解读:技术、量产与生态的深度剖析
  • 别再乱设过期时间了!深入Minio分享链接与临时凭证的时效性管理
  • 磁力搜索聚合工具:23个站点一站式资源查找解决方案
  • 2026年交通事故勘查系统市场升级:这样选更靠谱 - 速递信息
  • 厦门名包回收认准这一家:无套路、不压价、全程透明 - 奢侈品回收测评
  • 三步解密Python打包文件:从黑盒到源码的完整提取路径
  • 2026年新疆铁路汽车托运公司推荐:私家车托运/二手车托运/商务车托运优选服务商 - 品牌推荐官
  • 航空器配载与货运管理系统java总结
  • 扇形扎花机厂家市场破局:差异化竞争策略拆解
  • 避开这个大坑!LLC电源设计时,你的输出电容选对了吗?
  • 航班货运配载系统三次迭代代码分析与心得报告
  • 从个人项目仓库命名到完整项目构建:技术实践与开源思维
  • 歌词滚动姬:重新定义歌词时间轴同步的专业级工具
  • 数字孪生交互推演方法
  • IL-2R基因结构及表达调控研究进展
  • 编码相位梯度超表面太赫兹波束调控【附仿真】
  • 基于卷积神经网络的宠物识别系统
  • 交管部门选交通事故勘查系统的3档靠谱方案 - 速递信息
  • 3步掌握League Akari:英雄联盟玩家的智能工具箱完整指南
  • PaperDebugger:连接论文理论与代码实践的算法调试工具
  • NAFNet模型ONNX化实战:从PyTorch到移动端部署的完整链路解析
  • 魔兽争霸III地图编辑器终极指南:HiveWE如何让你快速创建精美地图
  • 黑客最爱的入口:RDP远程桌面还在用默认3389?企业安全加固完整手册(含双因素改造)
  • DOWNLOAD_METADATA_SIGNATURE_MISMATCH/26