news 2026/3/21 19:27:17

C语言---排序算法6---递归归并排序法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言---排序算法6---递归归并排序法

文章目录

  • 算法步骤
  • 递归实现代码
  • 优缺点分析
    • 优点
    • 缺点
  • 适用场景
  • 迭代法 vs 递归法
            • 学习视频推荐

归并排序(Merge Sort)是经典的分治算法,采用递归+合并的思路实现高效排序。其核心思想是将数组不断二分至最小单元(单个元素),然后逐步合并有序子序列,最终得到全局有序数组。

算法步骤

1、分解:将当前数组分为左右两个子数组。
2、递归:对左右子数组递归执行归并排序。
3、合并:将两个已排序的子数组合并为一个有序数组。

递归实现代码

代码实现1:

#include <stdio.h>#include <stdlib.h>// 合并两个有序数组 void merge(int arr[], int left, int mid, int right){int i, j, k;int n1=mid - left +1;int n2=right - mid;// 创建临时数组 int *L=(int*)malloc(n1 * sizeof(int));int *R=(int*)malloc(n2 * sizeof(int));// 复制数据到临时数组for(i=0;i<n1;i++)L[i]=arr[left + i];for(j=0;j<n2;j++)R[j]=arr[mid +1+ j];// 合并临时数组到原数组 i=0;j=0;k=left;while(i<n1&&j<n2){if(L[i]<=R[j]){arr[k]=L[i];i++;}else{arr[k]=R[j];j++;}k++;}// 复制剩余元素while(i<n1){arr[k]=L[i];i++;k++;}while(j<n2){arr[k]=R[j];j++;k++;}free(L);free(R);}// 归并排序递归函数 void mergeSort(int arr[], int left, int right){if(left<right){int mid=left +(right - left)/2;// 递归排序左右子数组 mergeSort(arr, left, mid);mergeSort(arr, mid +1, right);// 合并已排序的子数组 merge(arr, left, mid, right);}}// 测试用例 intmain(){int arr[]={12,11,13,5,6,7};int n=sizeof(arr)/ sizeof(arr[0]);printf("原始数组: ");for(int i=0;i<n;i++)printf("%d ", arr[i]);mergeSort(arr,0, n -1);printf("\n排序后数组: ");for(int i=0;i<n;i++)printf("%d ", arr[i]);return0;}

代码实现2(摘抄自菜鸟教程):

#include<stdio.h>#include<stdlib.h>#include<string.h>// 函数声明voidmerge_sort_recursive(intarr[],intreg[],intstart,intend);voidmerge_sort(intarr[],constintlen);intmain(){intarr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};intlen=sizeof(arr)/sizeof(arr[0]);// 计算数组长度merge_sort(arr,len);// 调用归并排序函数// 打印排序后的数组for(inti=0;i<len;i++){printf("%d ",arr[i]);}return0;}// 递归实现归并排序voidmerge_sort_recursive(intarr[],intreg[],intstart,intend){if(start>=end)return;intmid=start+(end-start)/2;intstart1=start,end1=mid;intstart2=mid+1,end2=end;merge_sort_recursive(arr,reg,start1,end1);merge_sort_recursive(arr,reg,start2,end2);intk=start;while(start1<=end1&&start2<=end2){reg[k++]=arr[start1]<arr[start2]?arr[start1++]:arr[start2++];}while(start1<=end1){reg[k++]=arr[start1++];}while(start2<=end2){reg[k++]=arr[start2++];}// 使用memcpy进行数组复制,提高效率memcpy(arr+start,reg+start,(end-start+1)*sizeof(int));}// 归并排序入口函数voidmerge_sort(intarr[],constintlen){int*reg=(int*)malloc(len*sizeof(int));if(reg==NULL){// 检查内存分配是否成功fprintf(stderr,"Memory allocation failed\n");exit(EXIT_FAILURE);}merge_sort_recursive(arr,reg,0,len-1);free(reg);// 释放内存}

优缺点分析

优点

1、时间复杂度稳定在O(n log n)
2、适合链表排序(不需要额外空间)
3、多线程环境下容易并行化

缺点

1、需要O(n)额外空间
2、递归调用有栈空间开销
3、小规模数组时常数因子较大

适用场景

1、数据量较大(通常n>1000)
2、需要稳定排序的场景
3、外部排序(磁盘数据排序)
4、链表排序实现

迭代法 vs 递归法

特性迭代法递归法
实现方式通过循环逐步合并子数组通过递归分解问题
空间开销仅需临时数组空间递归栈空间(可能栈溢出)
代码复杂度稍复杂(需手动管理边界)更简洁(分治逻辑直观)
学习视频推荐

数据结构合集 - 归并排序(非递归与递归算法过程, 效率分析, 稳定性分析)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/21 3:31:21

保姆级教程:2026年OpenClaw(Clawdbot)一键搭建套路及FQA

保姆级教程&#xff1a;2026年OpenClaw&#xff08;Clawdbot&#xff09;一键搭建套路及FQA。OpenClaw(原名Clawdbot/Moltbot)是一款开源的本地优先AI代理与自动化平台。它不仅能像聊天机器人一样对话&#xff0c;更能通过自然语言调用浏览器、文件系统、邮件等工具&#xff0c…

作者头像 李华
网站建设 2026/3/15 6:45:42

React Native for OpenHarmony:井字棋游戏的开发与跨平台适配实践

井字棋游戏的开发与跨平台适配实践 摘要1. 引言&#xff1a;为何选择井字棋作为 RNOH 游戏开发示例&#xff1f;2. 技术栈与开发环境2.1 核心依赖版本2.2 OpenHarmony 开发环境 3. 游戏核心数据模型与状态管理3.1 类型定义3.2 胜负判定算法 4. 核心交互逻辑实现4.1 格子点击处理…

作者头像 李华
网站建设 2026/3/15 18:44:33

开源神器!一句话生成完整短剧,从剧本到成片全自动化

告别"抽卡式"AI视频生成&#xff0c;这款工具让你像专业导演一样掌控每一帧 前言 你是否有过这样的困扰&#xff1f; 用 AI 生成视频&#xff0c;角色一换镜头就"变脸" 想做一个完整的短剧&#xff0c;但每个镜头都要单独生成&#xff0c;效率极低 生成…

作者头像 李华
网站建设 2026/3/15 18:44:29

数字图像处理篇---形态学梯度

一句话比喻 形态学梯度就像给物体的边缘“描金边”&#xff1a;用膨胀的“外扩版”减去腐蚀的“内缩版”&#xff0c;剩下的就是闪闪发光的轮廓线。 核心思想&#xff1a;边缘 膨胀 - 腐蚀 形态学梯度不是新操作&#xff0c;而是用膨胀结果减去腐蚀结果&#xff1a; 梯度图 …

作者头像 李华
网站建设 2026/3/19 7:40:05

开发报销单自动填写工具,导入发票信息(金额,日期,品类),自动填充报销单,核对无误后导出,支持按公司规范调整,节省报销时间。

1. 实际应用场景描述 场景&#xff1a; 小李是一名市场专员&#xff0c;每月要处理大量差旅、采购发票&#xff0c;手动填写报销单非常繁琐&#xff0c;容易出错。公司报销单有固定格式&#xff0c;但每次都要重新输入金额、日期、品类&#xff0c;还要按部门、项目分类&#x…

作者头像 李华