文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言递归实现归并排序详解

2024-04-02 19:55

关注

归并排序递归实现还是比较难理解的,感觉涉及递归一般理解起来都会比较有难度吧,但是看了b站视频,然后照着打下来,然后自己写了点注释,就发现不知不觉都大概懂了。

这里的归并讲的是升序排序

归并排序思路大概就是:先划分数组,将数组划分为左右半区,分成的左右半区,各自再划分左右半区,一直划分,直到最后左右半区的元素都为一个时,开始合并,因为都划分为一个元素了,那么此时两个元素的排序就非常简单了,只需要比较大小就可以排序了,那么回溯上去会发现每组都是两两有序了,那么直接再依次比较两组之间的排头元素即可,取较小的赋值给临时数组,然后排头元素就变成后一个元素,一直这么比较,直到两组数据有一组为空时,只需要将另一组不为空的接在临时数组后面即可,因为此时不为空的剩下的元素是有序的且都比此时有序的临时数组大,接完之后临时数组就变成有序的数组了,那么再将临时数组的元素复制到实际数组中去,最后释放临时数组空间,输出实际数组,归并排序结束,输出的元素也是排好序的元素了。

这样干讲一定很抽象

这是b站视频里的图,十分生动形象了吧。

在这里插入图片描述

代码如下(除了视频里的注释,还加了点自己的注释)

#include<bits/stdc++.h>
using namespace std;
void print_arr(int arr[], int n){
	for(int i=0; i<n; i++){
		printf("%d ", arr[i]);
	}
	printf("\n"); 
}
//合并 
void merge(int arr[], int tempArr[], int left, int mid, int right){
	//标记左半区第一个未排序元素
	int l_pos = left; 
	//标记右半区第一个未排序元素 
	int r_pos = mid+1;
	//合并数组由左右半区构成,临时数组的开始位置也就是左半区的开始位置 
	int pos = left;
	//合并
	//划分刚结束后左右半区其实各自只有一个元素,那么直接比较大小即为两个元素的排序。 
	while(l_pos <= mid && r_pos <= right){//当左右半区都含有元素时 
		if(arr[l_pos] < arr[r_pos]) //左半区第一个剩余元素更小 
		     tempArr[pos++] = arr[l_pos++];//赋值后pos+1,l_pos+1为下一次做准备 
	    else //右半区第一个剩余元素更小 
		     tempArr[pos++] = arr[r_pos++];
	}
	//当右半区元素合并完后左半区还有元素剩余,此时右半区有序且都比左半区元素大
	//那么直接将剩余的右半区元素接上即可 
	//合并左半区剩余的元素
	while(l_pos <= mid)tempArr[pos++] = arr[l_pos++]; 
	//同理 
	//合并右半区剩余的元素
	while(r_pos <= right)tempArr[pos++] = arr[r_pos++];
	//把临时数组中合并后的元素复制回原来的数组
	//tempArr此时已有序,只需利用left,right即排完序后的左右半区复制回arr数组即可 
	while(left <= right){
		arr[left] = tempArr[left];
		left++;
	}
}
//归并排序 
void msort(int arr[], int tempArr[], int left, int right){
	//如果只有一个元素,那么就不需要继续划分
	//由 mid = (left + right) / 2得,当只剩最后一个数时 mid会和left和right相等
	//即传入后的left和right会相等 
	if(left < right){  //left和right不相等,不止一个元素,需要继续划分 
		//找中间点 
		int mid = (left + right) / 2;
		//递归划分左半区 
		msort(arr, tempArr, left, mid);
		//递归划分右半区 
		msort(arr, tempArr, mid+1, right); 
		//当数组划分完毕时开始进行合并 
		//合并已经排序的部分 
		//left为左半区左边界
		//right为右半区右边界
		//mid为划分左右半区的分界(也是左半区的右边界) 
		merge(arr, tempArr, left, mid, right);
	} 
}
//归并入口 
void merge_sort(int arr[], int n){
	//分配一个辅助的数组,内存大小为 数组数*数据类型占位 
	int* tempArr = (int*)malloc(n * sizeof(int));
	 if(tempArr){
	 	//tempArr为临时数组, arr为需要排序的数组
		//排序下标为0至n-1,n为数组大小 
	 	msort(arr, tempArr, 0, n-1);
	 	free(tempArr);//释放内存空间 
	 }
	 else{
	 	printf("meet error");
	 }
}
int main(){
	int arr[] = {9, 5, 2, 7, 12, 4, 3, 1, 11};
	int n = 9;
	//打印原来的数组 
	print_arr(arr, n);
	//归并排序 
	merge_sort(arr, n);
	//打印排完序的数组 
	print_arr(arr, n);
	return 0;
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!  

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯