C语言实现归并排序算法

本文详细介绍了归并排序的基本原理及其非递归实现过程,并提供了完整的C语言代码示例。通过对原始序列进行逐步合并来达到排序目的,最终实现了一个长度为n的有序序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序(Merging Sort)的原理是假设初始序列含有n个记录,则可以看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或者1的子序列;再两两归并,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。

以下程序在DEV C++中调试运行通过。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
	int r[10];//用于存储要排序的数组,r[0]用作烧饼或临时变量
	int lenght; 
}SqList;
//将有序的SR[i...m]和SR[m+1...n]归并为有序的TR[i...n]
void Merge(int SR[],int TR[],int i,int m,int n)
{
	int j,k,l;
	for(j=m+1,k=i;i<=m&&j<=n;k++)//将SR中记录由小到大归并入TR
	{
		if(SR[i]<SR[j])
			TR[k]=SR[i++];
		else
			TR[k]=SR[j++];
	 } 
	if(i<=m)
	{
		for(l=0;l<=m-i;l++)
			TR[k+l]=SR[i+l];
	}
	if(j<=n)
	{
		for(l=0;l<=n-j;l++)
			TR[k+l]=SR[j+l];
	}
 } 

//将SR[]中相邻长度为s的子序列两两归并到TR[] 
void MergePass(int SR[],int TR[],int s,int n)
{
	int i=1;
	int j;
	while(i<=n-2*s+1)
	{
		Merge(SR,TR,i,i+s-1,i+2*s-1);//两两归并
		i=i+2*s; 
	}
	if(i<n-s+1)//归并最后两个序列 
	{
		Merge(SR,TR,i,i+s-1,n);
	}else//若最后只剩单个子序列 
		for(j=i;j<=n;j++)
			TR[j]=SR[j];
}
//对顺序表L做归并非递归排序
void MergeSort2(SqList *L)
{
	int* TR=(int*)malloc(L->lenght*sizeof(int));//申请额外空间
	int k=1;
	while(k<L->lenght)
	{
		MergePass(L->r,TR,k,L->lenght);
		k=2*k;//子序列长度加倍
		MergePass(TR,L->r,k,L->lenght);
		k=2*k; 
	 } 
 } 
 
int main()
{
	SqList L;
	int k;
	L.lenght=9;
	int temp[10] ={0,9,1,5,8,3,7,4,6,2};
	memcpy(L.r, temp, 10*sizeof(int));
	printf("归并排序前:"); 
	for(k=1;k<10;k++)
		printf("%d,",L.r[k]);
	printf("\n");
	MergeSort2(&L);
	printf("归并排序后:"); 
	for(k=1;k<10;k++)
		printf("%d,",L.r[k]);
	printf("\n");
}

运行结果如图所示。


该算法的时间复杂度为O(nlogn),空间复杂度为O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值