前言
基于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写出了道题,知道她有多么快乐,真的为她感到高兴。
现在重新抽空讲解些简单的算法,其实总会遇到一些小小的问题,却要花很多时间,但其实完成那刻还是热泪盈眶的。刚刚因为一个白痴的问题,搞了自己好久,结果出来的那刻,真的扇了自己一巴掌。哈哈哈。多少还是有点收获的。加油。