【C语言-数据结构】归并排序(使用分治递归来实现)

目录

基本思想

具体代码实现:

代码解释:


基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列区间有序。若将两个有序表合并成一个有序表,称为二路归并。

图解:

上面的解释比较官方。这里用自己的大白话来解释一下。

其归并排序的实现过程就是:

首先,先将一组数据分成两组,这里可以以中间值为界来划分。

然后,利用分治递归法,紧接着将这分开的两组以同样的以中间值为界的方法来划分为两组,一直到最后只剩一个数或为空的时候停下来。

停下来的这时,先将数据排序一下,也就是将这两组数据归并一下,然后将归并好的数据拷贝回原数据中去,最后回溯就ok了。

具体代码实现:




int main(){

	TestMergeSort();
	return 0;
}




void  TestMergeSort() {

	int a[] = {9, 10, 6, 5, 8, 1, 3, 4, 2};
	int len = sizeof(a) / sizeof(a[0]);


	MergeSort(a, len);
	PrintfArray(a, len);


}





 void MergeSort(int* a, int n) {

      int* tmp = (int*)malloc(sizeof(int) * n);//实现归并排序得额外开辟一个与原数据同样大小的空间
	
	 if (tmp == NULL) {
		 printf("malloc is fail");
		 exit(-1);
	 }

	 _MergeSort(a, 0, n - 1, tmp);

 }




void _MergeSort(int* a, int begin, int end, int* tmp) {//归并排序的主要实现代码

	 if (begin >= end) {//当递归到子区间只有一个或为空时回溯
		 return;
	 }

	 int mid = (begin + end) / 2;

	 //[begin, mid] [mid + 1,end]
	 //分治递归,让子区间变得有序
	 _MergeSort(a, begin, mid, tmp);
	 _MergeSort(a, mid + 1, end, tmp);


	 //归并
	 //也就是利用分治的思想,将一组数据看成两组,一组为[begin, mid]
	 //另一组为[mid + 1,end]
	 //然后分别从两组数据的开头开始比较,把较小的放入到临时创建的新数组当中去
	 //这样,当遍历完时,其临时创建的数组中的数据也就成为有序的了

	 int begin1 = begin, end1 = mid;
	 int begin2 = mid+1, end2 = end;
	 int i = begin;//临时创建数组拷贝归并好的数据时用来计数的变量

	 //当两组数据都不为空的时候
	 while (begin1 <= end1 && begin2 <= end2) {

		 if (a[begin1] <= a[begin2])
			 tmp[i++] = a[begin1++];
		 else
			 tmp[i++] = a[begin2++];
		
	 }


	 //当某一组数据为空的时候
	 while (begin1 <= end1) {
		 tmp[i++] = a[begin1++];
	 }
	 while (begin2 <= end2) {
		 tmp[i++] = a[begin2++];
	 }


	 //将归并且排序好了的数据拷贝回原数组中去
	 //记得加begin,因为有可能你拷贝的是已经归并到右边的那一组数据,也就是[mid + 1,end]
	 memcpy(a + begin,tmp + begin,(end - begin + 1) * sizeof(int));

 }

代码解释:

 if (begin >= end) {//当递归到子区间只有一个或为空时回溯
         return;
     }

     int mid = (begin + end) / 2;

     //[begin, mid] [mid + 1,end]
     //分治递归,让子区间变得有序
     _MergeSort(a, begin, mid, tmp);
     _MergeSort(a, mid + 1, end, tmp);

以上这一段代码主要是将数据进行分治递归,从而将数据实现到上面的画绿色横线的那一步。感兴趣的可以跟着代码画画递归实现图,会容易理解很多。

实现完之后,其总体上就是这样的:

紧接着来进行归并(先进行左区间的):

到这里左半区间就变得有序了,同样的,右半区间也可以一样的实现。到这,也就完成了归并排序的讲解了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值