排序算法--归并排序

赶时间的学习记录

归并排序法(Merge Sort,以下简称MS)是分治法思想运用的一个典范。

其主要算法操作可以分为以下步骤:
Step 1:将n个元素分成两个含n/2元素的子序列
Step 2:用MS将两个子序列递归排序(最后可以将整个原序列分解成n个子序列)
Step 3:合并两个已排序好的序列
易知,MS的关键在于Merge过程。对于这一过程的理解,算法导论中给出了一个形象的模型。
即假设桌面上有两堆已排序好的的牌,且每一堆都正面朝下放置。然后我们分别从两堆牌中选取顶上的一张牌(选取之后,堆顶端又会露出新的顶牌),选取较小的一张,放入输出堆,另一张放回。
重复这一步骤,最后直到一堆牌为空。由于两堆牌都是已排序,所以可知,只要将剩下的那堆牌盖到输出堆即完成整个排序过程。

以上来自百度百科,如果没看懂建议去B站找视频看看。

草稿:
排序算法--归并排序_第1张图片

完整代码:

#include
#include//分配空间需要用

void merge(int *a,int *temparr,int left,int mid,int right)//合并小问题
{
	int lpos=left,rpos=mid+1;
	int temppos=left;
	while(lpos<=mid && rpos<=right)
	{
		if(a[lpos]<a[rpos])temparr[temppos++]=a[lpos++];//排序,最小的先放入临时数组
		else temparr[temppos++]=a[rpos++];
	}
	while(lpos<=mid)//左边剩余的数直接放入临时数组
	{
		temparr[temppos++]=a[lpos++];	
	}
	while(rpos<=right)//右边剩余的数直接放入临时数组
	{
		temparr[temppos++]=a[rpos++];	
	}
	while(left<=right){a[left]=temparr[left];left++;}//排好序后将这一段的数据覆盖到原数组中
}


void divide_conquer(int *a,int *temparr,int left,int right)//划分成左右两边
{
	if(left<right)
	{
		int mid=(left+right)/2;
		divide_conquer(a,temparr,left,mid);
		divide_conquer(a,temparr,mid+1,right);//left和right都是数组的下标
		merge(a,temparr,left,mid,right);
	}
	
	
}

void mergesort(int *a,int len)//归并排序入口
{
	int *temparr=(int*)malloc(len*sizeof(int));//开辟临时数组,用来合并
	if(temparr)
	{
		divide_conquer(a,temparr,0,len-1);
		free(temparr);
	}else
	{printf("fail to allocate dedicated space!");}

}

int main()
{
	int a[]={3,44,40,37,20,1,2,50,15};
	int len=sizeof(a)/sizeof(int);
	int i;
	mergesort(a,len);
	for(i=0;i<len;i++)printf("%3d",a[i]);
	printf("\n");
	return 0;
}

这玩意感觉还是有点难,要多温习几遍才行。

你可能感兴趣的:(排序算法,算法,c语言)