归并排序,就是将前后相邻的多个有序序列归并成一个新的有序序列的过程。
这里,我们讲的是2路归并,也就是怎么将两个相邻序列归并成一个序列。
下面讲一下算法的思路:
1.如果当前序列多于一个元素,将其均分为两个序列
2.对每个序列递归地调用归并排序,就是为了实现每个序列都有序,所以需要进行排序
3.将已经排序好的两个序列归并成一个序列。
第3步的归并过程其实就是一个采用分治法进行排序的过程,我们通过新建一个数组,然后,不断地在原来两个序列的首端取出元素,进行对比,将较小的元素依次放入一个新建的数组中,当有一个数组取值取到了尽头的时候,将另一个数组的剩下部分直接放入新的数组,这样就完成了归并。
下面是代码实现:
#include "stdafx.h"
#include "malloc.h"
#include <iostream>
using namespace std;
//二路归并,将s中的片段i到m,和m+1到n归并起来
void Merge(int s[],int r[],int i,int m,int n)
{
int j=0,k=0;
for(j=m+1,k=i;i<=m&&j<=n;k++){
if (s[i]<s[j]){
r[k] = s[i++];
}else{
r[k] = s[j++];
}
}
//i,j记录的是下一个要排序的位置
//有一边先插值排序结束,将剩下的部分依次放入数组中
if (i<=m){
for (int t= 0;t<=m-i;t++){
r[k+t] = s[i+t];
}
}
if (j<=n){
for (int t= 0;t<=n-j;t++){
r[k+t] = s[j+t];
}
}
}
void MSort(int s[],int r[],int i,int j)
{
if (i==j)
{ r[j] = s[i];
}else{
int *tmp = (int *)malloc((j-i+1)*sizeof(int));
//int tmp[] = {0,0,0,0,0,0};
int m = (i+j)/2;//拆分
MSort(s,tmp,i,m);
MSort(s,tmp,m+1,j);
Merge(tmp,r,i,m,j);//归并
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[]={5,2,6,3,9,4};
int *b = (int *)malloc(sizeof(a));
//int c[] = {0,0,0,0,0,0};
MSort(a,b,0,5);
for (int i=0;i<=5;i++)
{
cout<<b[i]<<endl;
}
system("pause");
return 0;
}