分治法--归并排序(C++)


前言

基于C++的分治法中的归并排序


一、归并排序

归并排序是分治法中的一个完美的例子,归并排序主要是按照记录在序列中的位置对序列进行划分。这里我们应用归并排序方法对一个记录序列进行升序排序。

二、思路

1.问题

输入的序列为:2、4、7、5、8、1、3、6
对这序列进行升序处理。

2.算法

输入:未排序序列
输出:升序序列
1、如果s(数组第一位)==t(数组最后一位),则待排序区间只有一个值,无需排列,算法结束;
2、计算划分中点:m=(s+t)/2;
3、对前子半序列r[s]-r[m]进行升序排列;
4、对后子半序列r[m]-r[t]进行升序排列;
5、合并两个升序序列r[s]-r[m]和r[m]-r[t]。
在这里插入图片描述

具体细节详解过程见源码。
请添加图片描述

三、源码

//分治法--并归排序
#include <iostream>
using namespace std;

void Merge(int r[], int r1[], int s, int m, int t)
{
	int i = s, j = m + 1, k = s;
	//取前子序列r[i]和后子序列r[j]中的较小值放入临时数组r1[k]中
	while (i <= m && j <= t)
	{
		if (r[i] <= r[j]) r1[k++] = r[i++];
		else r1[k++] = r[j++];
	}
	//前子序列还未处理完 则进行收尾填充
	while (i <= m)
	{
		r1[k++] = r[i++];
	}
	//后子序列还未处理完 则进行收尾填充
	while (j <= t)
	{
		r1[k++] = r[j++];
	}
}


//对序列r[s]-r[t]进行归并排序
void Mergesort(int r[], int s, int t)
{
	int m, r1[1000];			//划分中间值,和开辟临时数组。
	if (s == t)return;			//递归的边界条件,只有一个记录,即已经有序。
	else
	{
		m = (s + t) / 2;		//划分
		Mergesort(r, s, m);		//并归排序前半个子序列
		Mergesort(r, m + 1, t);	//并归排序后半个子序列
		Merge(r, r1, s, m, t);	//合并两个有序子序列,结果存在临时数组r1中
		for (int i = s;i <= t; i++)	//将有序序列传入数组r中
		{
			r[i] = r1[i];
		}
	}
}


int main()
{
	//输入输出 测试数组
	int BeginTestList = 0, LenTestList;
	cout << "请输入你要测试的数值长度:";
	cin >> LenTestList;
	int* TestList = new int[LenTestList];
	cout << "请输入要测试的数组值:" ;
	for (int i = 0; i < LenTestList; i++)
	{
		cin >> TestList[i];
	}
	cout << "测试数组值(未排序):";
	for (int i = 0; i < LenTestList; i++)
	{
		cout << TestList[i] << " ";
	}
	cout << endl;

	//合并排序
	Mergesort(TestList, BeginTestList, LenTestList-1);
	cout << "测试数组值(已排序):";
	for (int i = 0; i < LenTestList; i++)
	{
		cout << TestList[i] << " ";
	}
	//释放空间
	delete[]TestList;
	return 0;
}

总结

总要热爱一些什么。这学期新建一个实验室小组,记得学妹说:“我就喜欢刷题的乐趣,它能够带给我很大的快乐,这就够了,对我来说。”深受触动。今天凌晨一点多,看到她朋友圈发的最后32s写出了道题,知道她有多么快乐,真的为她感到高兴。
现在重新抽空讲解些简单的算法,其实总会遇到一些小小的问题,却要花很多时间,但其实完成那刻还是热泪盈眶的。刚刚因为一个白痴的问题,搞了自己好久,结果出来的那刻,真的扇了自己一巴掌。哈哈哈。多少还是有点收获的。加油。

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值