归并排序C语言实现

归并操作的基本模式如下:

分解:把一个问题分解成与原问题相似的子问题

解决:递归的解各个子问题

合并:合并子问题的结果得到了原问题的解


分解,递归

void mergeSort(int data[],int low,int high)
{
	if (high > low)
	{
		int mid = (high + low)/2;
		mergeSort(data,low,mid);
		mergeSort(data,mid+1,high);
		merge(data,low,mid,high);
	}
}


整个执行过程如上图。

代码如下:

/************************************************************************
*归并排序,是将数组分成二组A,B,然后将A,B组各自再分成二组,
*依次类推,直到每个数组元素单独成为一个数组为止。
*单个元素的数组,相当于数组已经有序。如果两组组内的数据都是有序的,
*那么就可以将二组有序数据进行合并排序。
*这样通过先递归的分解数列,再合并数组就完成了归并排序。                                                                     
************************************************************************/
#include <stdio.h>
#include <stdlib.h>

void merge(int[],int,int,int);
void mergeSort(int[],int,int);
void print(int[],int);

void mergeSort(int data[],int low,int high)
{//对整个数组进行分裂,直到每个子数组都只含有一个元素为止
	if (high > low)
	{//进行递归分裂操作
		int mid = (high + low)/2;
		mergeSort(data,low,mid);
		mergeSort(data,mid+1,high);
		merge(data,low,mid,high);
	}
}

void merge(int data[],int low,int mid,int high)
{//进行归并操作
	int lLen=mid-low+1;
	int rLen=high-mid;
	int *leftArr=(int*)malloc(sizeof(int)*(lLen+1));
	int *rightArr=(int*)malloc(sizeof(int)*(rLen+1));

	for (int i=0;i<lLen;i++)
	{//用一个数组将分裂后的左数组存进来
		leftArr[i]=data[low+i];
	}

	for (int j=0;j<rLen;j++)
	{//用一个数组将分裂后的右数组存进来
		rightArr[j]=data[mid+1+j];
	}

	int i=0,j=0;
	int k=low;
	while (i<lLen && j<rLen)
	{//比较两个数组的元素,进行合并
		if (leftArr[i]<rightArr[j])
		{
			data[k++]=leftArr[i++];
		}else
		{
			data[k++]=rightArr[j++];
		}
	}
	while (i<lLen)
	{//当右数组已经全部存进data数组以后,左数组依然还有元素,将左数组剩余依次放到data数组最后
		data[k++]=leftArr[i++];
	}
	while (j<rLen)
	{//当左数组已经全部存进data数组以后,右数组依然还有元素,将右数组剩余依次放到data数组最后
		data[k++]=rightArr[j++];
	}
	free(leftArr);
	free(rightArr);
}

void print(int data[],int num)
{
	for (int i=0;i<num;i++)
	{
		printf("%d ",data[i]);
	}
	printf("\n");
}

int main()
{
	int data[]={0,9,8,7,6,5,4,3,2,1};
	int num = sizeof(data)/sizeof(int);
	printf("----------归并排序----------\n");
	print(data,num);
	mergeSort(data,0,num-1);
	print(data,num);
	return 0;
}


 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值