首页 > 其他分享 >29.归并排序

29.归并排序

时间:2023-06-26 19:13:16浏览次数:26  
标签:归并 int 29 mid A1 算法 数组 排序

研究了这么多算法以后,小桂子颇有收获,基本自认为排序算法已经全部掌握,于是就想卖弄一下自己的“算法内功”,另一方面为了交流推广,把这些算法传播出去,就召开一个全国算法大赛,集思广益,征集更牛逼的算法!
在算法大赛上,有两位白发葱葱的老者提出的算法让小桂子自惭形秽,感叹良多。。。

其中一位叫归并长老的老者,提出了如下的排序方法:

当两个组数据已经有序,我们可以通过如下方式(以下简称归并大法)让两组数据快速有序

我们可以依次从两组中取最前面的那个最小元素依次有序放到新的数组中,然后再把新数组中有序的数据拷贝到原数组中,快速完成排序。

依靠这种思想,归并长老提出了如下的排序方法!

具体步骤
对于下面这一组待排序的数组

先以中间为界,把其均分为A 和B 两个数组(如果是奇数个,允许两组数相差一个)

如果A 和B 两组数据能够有序,则我们可以通过上面的方式让数组快速排好序。

此时,A 组有4 个成员,B 组有5个成员,但两个数组都无序,然后我们可以采用分治法继续对A组和B组进行均分,以A 组为例,又可以均分A1和A2两个组如下:

均分后,A1组和A2组仍然无序,继续利用分治法细分,以A1组为例,A1又可分成如下两组

数组细分到一个元素后,这时候,我们就可以采用归并法借助一个临时数组将数组A1 有序化!A2 同理!

依次类推,将A1组和A2组归并成有序的A组, B 组同理!

最后,将A和B组使用归并大法合并,就得到了完整的有序的结果!

代码实现:

1.数组前后两部分均有序排列

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void mergeAdd_demo(int arr[], int left, int mid, int right)
{
	int temp[64] = { 0 };

	int i = left;//指向左边数组最小的元素位置
	int j = mid;//指向右边数组最小的元素位置
	int k = 0;//临时数组的下标

	while (i < mid && j <= right)
	{
		if (arr[i] < arr[j])
		{
			temp[k++] = arr[i++];
		}
		else
		{
			temp[k++] = arr[j++];
		}
	}

	while (i < mid)
	{
		temp[k++] = arr[i++];
	}
	while (j <= right)
	{
		temp[k++] = arr[j++];
	}

	//把temp中的内容拷贝到arr数组中
	memcpy(arr + left, temp,  sizeof(int)*(right - left + 1));
}

int main()
{
	int beauties[] = { 1, 3, 6, 7, 2, 4, 5, 8};

	int len = sizeof(beauties) / sizeof(beauties[0]);

	int mid = len / 2;

	mergeAdd(beauties, 0,  mid, len - 1);

	printf("执行归并大法后:\n");
	for (int i = 0; i < len; i++)
	{
		printf("%d ", beauties[i]);
	}

	system("pause");
	return 0;
}

2.数组前后两部分无序排列

void mergeAdd(int arr[], int left, int mid, int right, int *temp)
{
	//int temp[64] = { 0 };

	int i = left;//指向左边数组最小的元素位置
	int j = mid;//指向右边数组最小的元素位置
	int k = left;//临时数组的下标

	while (i < mid && j <= right)
	{
		if (arr[i] < arr[j])
		{
			temp[k++] = arr[i++];
		}
		else
		{
			temp[k++] = arr[j++];
		}
	}

	while (i < mid)
	{
		temp[k++] = arr[i++];
	}
	while (j <= right)
	{
		temp[k++] = arr[j++];
	}

	//把temp中的内容拷贝到arr数组中
	memcpy(arr + left, temp + left, sizeof(int) * (right - left + 1));
}

void mergeSort(int arr[], int left, int right, int* temp)//归并排序
{
	int mid = 0;

	if (left < right)
	{
		mid = left + (right - left) / 2;
		mergeSort(arr, left, mid, temp);
		mergeSort(arr, mid + 1, right, temp);
		mergeAdd(arr, left, mid + 1, right, temp);
	}
}

int main()	
{
	int beauties[] = { 10, 11, 12, 13, 2, 4, 5, 8};

	int len = sizeof(beauties) / sizeof(beauties[0]);

	int* temp = new int[len];

	int mid = len / 2;

	mergeSort(beauties, 0, len - 1, temp);
	//mergeAdd(beauties, 0,  mid, len - 1, temp);

	printf("执行归并大法后:\n");
	for (int i = 0; i < len; i++)
	{
		printf("%d ", beauties[i]);
	}

	system("pause");
	return 0;
}

参考资料来源:

奇牛学院

标签:归并,int,29,mid,A1,算法,数组,排序
From: https://www.cnblogs.com/codemagiciant/p/17506511.html

相关文章

  • 34. 在排序数组中查找元素的第一个和最后一个位置
    给你一个按照非递减顺序排列的整数数组nums,和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值target,返回[-1,-1]。你必须设计并实现时间复杂度为O(logn)的算法解决此问题。示例1:输入:nums=[5,7,7,8,8,10],target=......
  • 28.希尔排序
    插入排序虽好,但是某些特殊情况也有很多缺点,比如像下面这种情况:169前的元素基本不用插入操作就已经有序,元素1和2的排序几乎要移动数组前面的所有元素!!!于是,有个老帅哥就提出了优化此问题的希尔排序!希尔排序是希尔(DonaldShell)于1959年提出的一种排序算法。希尔排序也是......
  • 集成板级摄像头行业市场调研及趋势分析报告2023-2029
    2023-2029全球集成板级摄像头行业调研及趋势分析报告2022年全球集成板级摄像头市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国集成板级摄像头市场占据全球约%的市场份额,为全......
  • 家用电器用电机行业市场调研及趋势分析报告2023-2029
    2023-2029全球家用电器用电机行业调研及趋势分析报告2022年全球家用电器用电机市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国家用电器用电机市场占据全球约%的市场份额,为全......
  • LLM-Blender:大语言模型排序融合框架
    随着Alpaca,Vicuna,Baize,Koala等诸多大型语言模型的问世,研究人员发现虽然一些模型比如Vicuna的整体的平均表现最优,但是针对每个单独的输入,其最优模型的分布实际上是非常分散的,比如最好的Vicuna也只在20%的任务里比其他模型有优势。有没有可能通过集成学习来综合诸多开源的「......
  • ORA-29278: SMTP transient error: 421 Service not available
    ORA-29278:SMTPtransienterror:421Servicenotavailable一般来说,很可能是邮件服务器连接不上p_conn:=utl_smtp.open_connection('xx.xx.xxx.xxx',xxx);解决方法也很简单,将ip改为正确的邮件服务器ip即可......
  • 27.插入排序
    自从上次小桂子发现了冒泡排序后,他开始相信自己的聪明才智比伴读小书童居然要高,所以他更加热衷于排序算法研究了,没事的时候,时不时找几个宫女演练一下,这时他又发现了一个新的排序方式,对于一下宫女们的队列:1.首先,我们只考虑第一个元素,从第一个元素171开始,该元素可以认为已经被排......
  • C++面试八股文:std::array如何实现编译器排序?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第25面:面试官:array熟悉吗?二师兄:你说的是原生数组还是std::array?面试官:你觉得两者有什么区别?二师兄:区别不是很大,原生数组(非动态数组)和std::array都在栈上开辟空间,初始化的时候需要提供数组长度,且长度不可改变。有一点区别的是,st......
  • C++面试八股文:std::array如何实现编译器排序?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第25面:面试官:array熟悉吗?二师兄:你说的是原生数组还是std::array?面试官:你觉得两者有什么区别?二师兄:区别不是很大,原生数组(非动态数组)和std::array都在栈上开辟空间,初始化的时候需要提供数组长度,且长度不可改变。有一点区别的是,std......
  • 26.冒泡排序
    每当皇帝选妃时,首席太监小桂子总是忍不住在旁边偷窥这些候选的美女,有一次他发现做为伴读小书童的你居然犯了个常人都可以轻易看出的错误,有几位候选的美女站成如下一排:当我们采用前面的选择排序时,我们仍然要将候选者遍历5遍,才能完成最终的排序,但其实,本身这些美女除了第一个外,已经......