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

搜索建站商城开发价格服务

搜索建站,商城开发价格服务,直播app源码,修改网站后台地址本文旨在讲解归并排序的实现#xff08;递归及非递归#xff09;搬好小板凳#xff0c;干货来了#xff01; 前序#xff1a; 在介绍归并排序之前#xff0c;需要给大家介绍的是什么是归并#xff0c;归并操作#xff0c;也叫归并算法#xff0c;指的是将两个顺序序列…本文旨在讲解归并排序的实现递归及非递归搬好小板凳干货来了 前序 在介绍归并排序之前需要给大家介绍的是什么是归并归并操作也叫归并算法指的是将两个顺序序列合并成一个顺序序列的方法相信不少小伙伴之前都做过合并两个有序链表或者两个有序数组的例题归并就是将两个数组或链表合并成一个链表或数组还得保证与其原来的顺序相同那么归并排序就是用到了归并这个思想将一组元素完成排序的算法 归并排序的介绍  归并排序MERGE-SORT是建立在归并操作上的一种有效的排序算法,该算法是采用分治法Divide and Conquer的一个非常典型的应用。将已有序的子序列合并得到完全有序的序列即先使每个子序列有序再使子序列段间有序。若将两个有序表合并成一个有序表称为二路归并。 归并排序的时间复杂度和空间复杂度 时间复杂度ON*logN因为其是一种二叉树结构其高度为logN,每层需要排序的个数都是N个所以其时间复杂度为ON*logN。 空间复杂度因为创建了一个新的数组所以其空间复杂度为ON 归并排序的思想与思路 归并排序就是本质上是分治的方法来实现的是将一组数据分割成若干组有序数组然后对这若干个有序数组两两进行归并即可得到我们想要的排序 归并排序的思路图 归并排序的动态图展示 归并排序的大致实现思路  归并排序其实现的思路其实很简单就是将一组数据分割分割到若干组有序数组然后两两进行归并那么如何保证分割的数组为有序数组呢这其实很简单当分割到数组中只有一个元素的时候那么该数组就是有序的数组了然后进行归并拷贝到原数组上即可 归并排序的代码实现 C版本递归 void _MergeSort(int* a, int left, int right, int* tem) {//当再次需要调用的区间不存在时返回即可if (left right) //很显然left不会大于right保险起见加上大于条件没有影响{return;}//每次取出中间坐标用于下次的左半边的递归右半边递归同理int mid (left right) / 2;_MergeSort(a, left, mid, tem);_MergeSort(a, mid 1, right, tem);//到此分割区间已经结束每组区间都能保证时有序的了下一步就开始进行归并int begin1 left, end1 mid;int begin2 mid 1, end2 right;int i left; //i用于对tem数组的下标进行表示//下面开始归并两个有序数组当两个有序数组其中一个遍历完成就退出循环while (begin1 end1 begin2 end2){if (a[begin1] a[begin2]){tem[i] a[begin1];}else{tem[i] a[begin2];}}while (begin1 end1){tem[i] a[begin1];}while (begin2 end2){tem[i] a[begin2];}//归并结束后将tem数组中的数据拷贝到元素组中相应的位置即可memcpy(a left, tem left, sizeof(int)*(right - left 1));//个数为右边界减去左边加1因为为闭区间//至此归并结束拷贝结束! } void MergeSort(int* a, int n) {//在堆上申请开辟一个tem数组用来最后拷贝到原数组中int* tem (int *)malloc(sizeof(int) * n);//因为存在递归的调用所以再创建一个函数若仍在此函数上重复调用时则会重复开辟新的空间可能导致空间不足_MergeSort(a, 0, n - 1, tem);//用完之后释放到tem数组free(tem); } 需要注意的是当进行递归归并排序的时候需要注意返回的条件当区间不存在或者区间内部只有一个元素的时候就可以返回了还需要注意的是因为要进行拷贝不能在原数组上直接拷贝所以需要创建一个新的数组用来存储归并后的元素的位置最后归并结束重新拷贝到原数组中即可 C版本非递归 分段拷贝 // 归并排序非递归实现//思路如下要想实现归并排序的非递归那么需要注意分组从每组一个元素开始因为当只有一个元素的时候默认是有序的然后 //进行归并拷贝即可每组一个元素遍历结束之后进行每组两个依次进行每组2倍个元素进行归并当每组的元素为所有元素的一半或大于一半 //即可完成排序需要特别注意的是进行非递归归并排序的时候需要注意区间的取值在此有两个拷贝方式一种是整体拷贝一组是归并一段拷贝一段//进行非递归实现归并的时候也需要创建一个新的数组不能在原数组上进行对数据的改变因为可能会造成数据的覆盖导致数据不能完成排序 //创建一个新数组然后让每组元素为一个依次递增二倍进行归并拷贝直至每组的元素个数大于数组个数结束归并即可完成排序//下面先来进行分段拷贝 //void MergeSortNonR(int* a,int n) //{ // //注意gap代表的是每组归并时的元素的个数 // int gap 1; // int* tem (int*)malloc(sizeof(int) * n); // while (gap n) //当gap大于n时结束循环即可完成 // { // int j 0; // //每组为一个的进行遍历 // for (int i 0; i n ; i2*gap) // { // // //每组个数为1的进行归并排序 // //区间范围如下! // int begin1 i, end1 i gap - 1; // int begin2 i gap, end2 i 2 * gap - 1; // // //当end1n,begin2n时不需要进行归并 // if (end1 n||begin2n) // { // break; // } // // //对end2边界进行修改 // if (end2 n) // { // end2 n-1; // } // // //开始进行归并拷贝 // while (begin1 end1 begin2 end2) // { // if (a[begin1] a[begin2]) // { // tem[j] a[begin1]; // } // else // { // tem[j] a[begin2]; // } // } // while (begin1 end1) // { // tem[j] a[begin1]; // } // while (begin2 end2) // { // tem[j] a[begin2]; // } // // //注意需要注意的是当求元素的个数时应该用end2-i,不能减去begin1因为begin1每次都会改变记录的不再是数组开始拷贝的地方 // memcpy(a i, tem i, sizeof(int) * (end2 - i 1)); // } // gap * 2; // } // free(tem); //} 整体拷贝 //整段拷贝 void MergeSortNonR(int* a, int n) {//注意gap代表的是每组归并时的元素的个数int gap 1;int* tem (int*)malloc(sizeof(int) * n);while (gap n) //当gap大于n时结束循环即可完成{//j的声明必须写在for循环的外面因为若写到for循环内部时在每组循环都会将原来归并好的数据放到前面的那些位置//导致以及归并好的又被覆盖导致排序失败每组的归并都放在前两组内部导致不能将全部归并结束int j 0;//每组为一个的进行遍历for (int i 0; i n; i 2 * gap){//每组个数为1的进行归并排序//区间范围如下!int begin1 i, end1 i gap - 1;int begin2 i gap, end2 i 2 * gap - 1;//当end1n,begin2n时不需要进行归并if (end1 n){end1 n - 1;//将第二块区间设置为不存在的区间如果设置为n-1那么会造成对最后一个数据的重复使用拷贝导致排序错误begin2 n;end2 n - 1;}else if (begin2 n){begin2 n;end2 n - 1;}else if(end2n){end2 n - 1;}//开始进行归并拷贝while (begin1 end1 begin2 end2){if (a[begin1] a[begin2]){tem[j] a[begin1];}else{tem[j] a[begin2];}}while (begin1 end1){tem[j] a[begin1];}while (begin2 end2){tem[j] a[begin2];}//注意需要注意的是进行整段拷贝的时候不需要再从abegin1的位置开始拷贝啦直接将所有tem中的元素拷贝到原数组即可}memcpy(a, tem, sizeof(int) * n);gap * 2;}free(tem); } 需要注意的是非递归的归并排序整体拷贝和分段拷贝大致思路是一样的只是最后进行memcpy的起始位置和个数有所不同相关细节与思路都在源代码上加有注释标明需要注意的是当进行整体拷贝的时候用于标记tem数组的j的坐标的定义一定要在for循环外部定义赋值若在内部赋值定义则每进行一次都会覆盖原来已经归并好的数据上面导致归并排序不能正确进行 今日的归并排序分享到此结束欢迎大家积极评论支持。若有不足及补充及时提出必将改正
http://www.zqtcl.cn/news/922133/

相关文章:

  • 品牌做网站网上接外包项目
  • 购物网站设计图百安居装修报价清单
  • 做网站要提供什么莱芜综合频道莱芜新闻
  • 网站怎么做前后台存取马鞍山市网站建设公司
  • 北京西站到北京南站软件定制外包公司
  • 网站开发手机端游戏网站设计风格有哪些
  • 网站建设开发感想网站建设公司接单
  • 建立网站后怎样收费吗设计图纸网站
  • asp网站密码从零开始做一个网站需要多少钱
  • 网站建设中需求分析报告微信 网站 优劣势
  • 湖南建设长沙网站建设价格关于网站的建设论文
  • 玉林网站制作网站建设的常用词
  • linux系统网站空间用凡科做网站的费用
  • 如何给别人做网站百度推广助手app
  • 哈市哪里网站做的好新颖的网站策划
  • 网站建设 方案书微信登录wordpress免费
  • 兰州网站建设企业名录洛可可设计公司估值
  • 广州做网站地方兰州做网站的公司有哪些
  • 招标网站哪个好适合学生做网站的图片
  • 台州seo网站排名优化外包服务公司
  • 汉川网站推广服务网页站点不安全
  • wdcp网站搬家嘉兴做网站优化的公司
  • 网站规划和建设度假区网站建设方案
  • 做网站前端用什么软件好在线种子资源网
  • 怎样修改网站关键词昌平做网站的公司
  • 网站建设调研文档网站最下面版权模板
  • 建外贸网站有效果吗开发电商平台需要多少钱
  • 成都网站建设维护网页制作价格私活
  • 建设银行网站登陆不上做本地的分类信息网站
  • 公司网站建设哪里实惠网页设计作业百度网盘