分治法之归并排序(递归+分治)
/*
归并排序
思想:
1.分而治之,将一个无序的数列一直一分为二,直到分到序列中只有一个数的时候,这个序列肯定是有序的,因为只有一个数,然后将两个只含有一个数字的序列合并为含有两个数字的有序序列,这样一直进行下去,最后就变成了一个大的有序数列
2.递归的结束条件是分到最小的序列只有一个数字的时候
时间复杂度分析:
最坏情况:T(n)=O(n*lg n)
平均情况:T(n)=O(n*lg n)
稳定性:稳定(两个数相等的情况,不用移动位置
辅助空间:O(n)
特点总结:
高效
耗内存(需要一个同目标数组SR相同大小的数组来运行算法)
*/
#include<stdio.h>
#define max 1024
int SR[max],TR[max];
int merge(int SR[],int TR[],int s,int m,int t)//SR代表两个有序序列构成的序列,s表示起始位置,m表示两个序列的分解位置,但是SR[m]仍是属于前面一个序列,t表示结束位置
{//TR是一个空数组,用来存放排序好之后的数字
int i=s,j=m+1,k=s;
while(i<=m&&j<=t)
{
if(SR[i]<SR[j])
{
TR[k++]=SR[i++];
}else
{
TR[k++]=SR[j++];
}
}
while(i<=m)//当前面一个序列有剩余的时候,直接把剩余数字放在TR的后面
{
TR[k++]=SR[i++];
}
while(j<=t)//当后面一个序列有剩余的时候,直接把剩余数字放在TR的后面
{
TR[k++]=SR[j++];
}
return 0;
}//该函数要求SR是由两个有序序列构成
void copy(int SR[],int TR[],int s,int t)//把TR赋给SR
{
int i;
for(i=s;i<=t;i++)
{
SR[i]=TR[i];
}
}
int mergesort(int SR[],int s,int t)
{
if(s<t)//表示从s到t有多个数字
{
int m=(s+t)/2;//将序列一分为二
mergesort(SR,s,m);//前一半序列继续进行归并排序
mergesort(SR,m+1,t);//后一半序列同时进行归并排序,
//以上递归调用的结束条件是s!<t,也就是进行分到只有一个数字进行归并排序的时候,一个序列只有一个数字,那么这个序列肯定是有序的
//以上都是属于“分”的阶段,目的是获得两个有序的数列
merge(SR,TR,s,m,t);//对这两个有序的数列,进行排序,变成一个同样大小但是有序的数列
copy(SR,TR,s,t);//将在TR中排序好的数列给SR,方便SR递归调用归并排序,因为每次两个归并排序的结果都是保存在TR中的,现在要进行下一步就必须在TR数列的基础上面=进行,所以我们把TR给SR
}else//表示从s到t只有一个数字(s==t),或者没有数字(s>t)
{
;//空,也可省略,加一个else只是为了更好的理解程序
}
return 0;
}
int main()
{
int n;
printf("请输入排序数字的个数:\n");
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
{
scanf("%d",&SR[i]);
}
mergesort(SR,0,n-1);//升序排列
for(i=0;i<n;i++)
{
printf("%d ",SR[i]);
}
printf("\n");
return 0;
}
心之所向,素履以往
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南