当前位置: 首页 > article >正文

归并排序——

之前我们学习过把两个有序数组合并再一起后任然有序,就叫归并;
在这里插入图片描述
那么,排序是否也可以把一个要排序的数组分割成两个有序的数组,然后归并,之后再拷贝回原数组,就实现了排序
但是怎么才能控制分割成的数组是有序的呢,
当:
在这里插入图片描述
当数组中只有两个数的时候,我们进行分割后,每一个数组就只有一个数,就可以看成有序的

有了这个思想,那么我们就递归分个要排序的数组,当递归分割到只有两个数的时候,在归并
在这里插入图片描述

void Merge(int* a, int* tmp, int begin, int end)
{
	//分割
	if (begin == end)
	{
		return;
	}
	int mid = (begin + end) / 2;
	Merge(a, tmp, begin, mid);
	Merge(a, tmp, mid + 1, end);
	//归并
	int begin1 = begin;
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = end;
	int dex = begin;
	while (begin1<=end1&&begin2<=end2)
	{
		if (a[begin1] <= a[begin2])
		{
			tmp[dex] = a[begin1];
			dex++;
			begin1++;
		}
		else
		{
			tmp[dex] = a[begin2];
			dex++;
			begin2++;
		}
	}
	while (begin1 <= end1)
	{
		tmp[dex] = a[begin1];
		dex++;
		begin1++;
	}
	while (begin2 <= end2)
	{
		tmp[dex] = a[begin2];
		dex++;
		begin2++;
	}
	//拷贝回去
	memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int));
	

}
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	Merge(a,tmp,0,n-1);
}

非递归的写法:
之前的快速排序是借助栈来实现非递归,因为每次分完之后他就找出了key的位置,那个区间出栈后不需要再用到
但是归并排序的话,分割完后,还要用到之前的分割区间,但是都已经出栈了,就找不到了。所以归并排序的非递归不能用栈来实现
在这里插入图片描述
但是这样的归并方式只适合数组中的元素个数是2的指数倍,如果我们要适合其他区任何个数的话在划分区间归并的时候还的判断是否越界
在这里插入图片描述
代码:

void MergeSortNoNs(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);

	int pas = 1;
	while (pas<n)
	{
		for (int i = 0; i < n; i += pas * 2)
		{
			int begin1 = i; int end1 = i + pas - 1;
			int begin2 = i + pas; int end2 = i + 2 * pas - 1;
			//越界管理
			if (begin2 >= n)
			{
				break;
			}
			if (end2 >= n)
			{
				end2 = n - 1;
			}
			int dex = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[dex] = a[begin1];
					dex++;
					begin1++;
				}
				else
				{
					tmp[dex] = a[begin2];
					dex++;
					begin2++;
				}
			}
			while (begin1 <= end1)
			{
				tmp[dex] = a[begin1];
				dex++;
				begin1++;
			}
			while (begin2 <= end2)
			{
				tmp[dex] = a[begin2];
				dex++;
				begin2++;
			}
			//拷贝回去
			memcpy(a + i, tmp+i, (end2-i+1) * sizeof(int));

		}
		pas *= 2;
	}
}

http://www.kler.cn/news/108368.html

相关文章:

  • san.js源码解读之模版解析(parseTemplate)篇——readCall函数
  • Python-自动化绘制股票价格通道线
  • 【Linux】:进程程序替换
  • IP应用场景API的反欺诈潜力:保护在线市场不受欺诈行为侵害
  • 《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码
  • SQL注入原理及思路(mysql)
  • EASYX动画效果实现
  • 【网安AIGC专题10.19】论文6:Java漏洞自动修复+数据集 VJBench+大语言模型、APR技术+代码转换方法+LLM和DL-APR模型的挑战与机会
  • MAYA教程之模型的UV拆分与材质介绍
  • 黑豹程序员-架构师学习路线图-百科:API接口测试工具Postman
  • 8.循环神经网络
  • matlab中字符串转换为数字(str2double函数)
  • 【java爬虫】公司半年报数据展示
  • 明星艺人类的百度百科怎么创建 ?
  • Spring使用注解进行注入
  • 网络综合和简化实频理论学习概述
  • mysql查看数据表文件的存放路径
  • python—openpyxl操作excel详解
  • react中的函数柯里化
  • DWA算法,仿真转为C用于无人机避障
  • CleanMyMac X2024永久免费版mac电脑管家
  • Vue 项目中使用 Pinia 状态管理详细教程
  • 06、SpringCloud -- 订单详情界面实现
  • 阿里云服务器—ECS快速入门
  • 黑客技术(网络安全)—小白自学
  • Jupyter Notebook还有魔术命令?太好使了
  • 【解决方案】ubuntu 解决办法 ImportError: cannot import name ‘_gi‘ from ‘gi‘
  • 软路由安装code-server配置和配置Nodejs开发环境
  • Lvs+Nginx+NDS
  • 【实用网站分享】