2026/1/13 0:01:42
网站建设
项目流程
共享虚拟主机做网站够用么,佛山互联网公司有哪些,给网站做排名优化学什么好处,强的网站建设明细报价表归并排序
归并排序——最常见的分治排序算法#xff1b;把两个已经有序的数组合并成一个有序数组
一、归并排序思路
分#xff1a;递归地把当前区间 [left, right] 一分为二#xff0c;直到区间长度 ≤1。治#xff1a;把两个已经有序的子区间合并成一个有序区间。合并时需…归并排序归并排序——最常见的分治排序算法把两个已经有序的数组合并成一个有序数组一、归并排序思路分递归地把当前区间 [left, right] 一分为二直到区间长度 ≤1。治把两个已经有序的子区间合并成一个有序区间。合并时需要额外 O(n) 的辅助空间时间复杂度稳定 O(n log n)是稳定排序。二、核心过程功能把两个有序子数组 a[low…mid] 和 a[mid1…high] 原地归并到临时数组 tmp最后再拷回去。关键点用双指针 i、j 分别扫描左右两段每次把较小的元素放到 tmp[k]指针后移某一段耗尽后把另一段剩余元素全部追加最后把 tmp[low…high] 复制回原数组对应位置。三、完整代码#includestdio.h#includestdlib.h#includestring.h/* 合并两个有序区间 a[low..mid] 与 a[mid1..high] */staticvoidmerge(int*a,intlow,intmid,inthigh){intilow,jmid1,k0;int*tmpmalloc((high-low1)*sizeof(int));if(!tmp){perror(malloc);exit(EXIT_FAILURE);}/* 二路归并 */while(imidjhigh)tmp[k](a[i]a[j])?a[i]:a[j];while(imid)tmp[k]a[i];while(jhigh)tmp[k]a[j];/* 拷回原数组 */memcpy(alow,tmp,(high-low1)*sizeof(int));free(tmp);}/* 归并排序递归主体 */staticvoidmerge_sort(int*a,intlow,inthigh){if(lowhigh){intmidlow(high-low)/2;/* 防溢出 */merge_sort(a,low,mid);merge_sort(a,mid1,high);merge(a,low,mid,high);}}/* 对外接口排序长度为 n 的整型数组 */voidmerge_sort_int(int*a,size_tn){if(n1)merge_sort(a,0,(int)n-1);}/* ---- 测试 ---- */intmain(void){intarr[]{8,3,6,7,1,5,2,4};size_tnsizeof(arr)/sizeof(arr[0]);merge_sort_int(arr,n);for(size_ti0;in;i)printf(%d%c,arr[i],i1n?\n: );return0;}四、常见变形与考点链表归并排序链表无法随机拆分用快慢指针找中点然后递归归并空间可做到 O(log n)递归栈。外排序文件太大内存放不下先分段生成有序临时文件再做多路归并。逆序对在 merge 过程中若左边元素 右边元素则左边剩余元素都与该右边元素构成逆序对可顺手统计。原地归并经典算法有 “旋转法” 或 “缓冲法”但实现复杂且常数大实际工程里仍用辅助数组。五、复杂度小结时间每次合并 O(n)共 log₂n 层 ⇒ O(n log n)空间辅助数组 O(n) 递归栈 O(log n)稳定性稳定相等元素相对顺序不变