1. 递归实现归并排序
1) 基本思想:
将待排元素分成大小大致相同的2个子集,分别对2个子集合进行排序,最终将排好序的子集合合并 就会得到一个排好序的集合 即为所求
设归并排序的当前区间是R[low..high],分治法的三个步骤是:
① 分解:将当前区间一分为二,即求分裂点
② 求解:递归地对两个子区间R[low..mid]和R[mid+1..high] 进行归并排序;
③ 组合:将已排序的两个子区间R[low..mid]和R[mid+1..high] 归并为一个有序的区间R[low..high]。
递归的终结条件:子区间长度为1(一个记录自然有序)。
2) 具体过程如下图所示:
3) 代码实现
/*
数组a[]为待排序数组,数组b[]用来存放已排好序的数
left、right分别为待排序数组最左端和最右端的下标
mid为数组下标的中点
*/
#include
#include
using namespace std;
#define maxn 100
int num[maxn];
// 将待排序集合一分为二,直至待排序集合只剩下一个元素为止,
// 然后不断合并两个排好序的数组段
template
void MergeSort(Type a[],int left,int right)
{
Type *b=new Type [maxn];
if(left
{
int i=(left+right)/2; //取数组中点,将数组尽量均等划分
MergeSort(a,left,i); //将左半段进行递归排序
MergeSort(a,i+1,right); //将右半段进行递归排序
Merge(a,b,left,i,right); //合并到数组b
Copy(a,b,left,right); //复制到数组a
}
}
// 将已排好序的数组合并到数组b[]中
template
void Merge(Type a[],Type b[],int left,int mid,int right)
{
int i=left;
int j=mid+1;
int k=left;
while(i<=mid && j<=right) //i的取值范围为 [left,m], j的取值范围为 [m+1,right]
{
if(a[i]
b[k++]=a[i++];
else
b[k++]=a[j++];
}
if(i>mid) //说明右边的数组的元素个数多
for(int z=j;z<=right;z++)
b[k++]=a[z];
else
for(int z=i;i<=mid;i++)
b[k++]=a[z];
}
// 将数组b[]中的数复制到数组a[]中
template
void Copy(Type a[],Type b[],int left,int right)
{
for(int i=left;i<=right;i++)
a[i]=b[i];
}
int main()
{
int n;
while(cin>>n)
{
for(int i=0;i
cin>>num[i];
MergeSort(num,0,n-1);
for(int i=0;i
cout<
}
system("pause");
return 0;
}
/*
7
49 38 65 97 76 13 27
*/
2. 非递归实现归并排序
1) 基本思想:
将数组中的相邻元素两两配对。用Merge()函数将他们排序,构成n/2组长度为2的排序好的子数组段,然后再将他们合并成长度为4的子数组段,如此继续下去,直至整个数组排好序
2) 具体过程如下图所示:
例1:8 3 2 6 7 1 5 4
例2:49 38 65 97 76 13 27
例2:49 38 65 97 76 (如上图)
3) 代码实现
#include
#include
using namespace std;
#define maxn 100
int num[maxn];
template
void MergeSort(Type c[],int n)
{
Type *d=new Type [n];
int s=1;
while(s
{
MergePass(c,d,s,n); //合并到数组d
s+=s;
MergePass(d,c,s,n); //合并到数组c
s+=s;
}
}
// 合并大小为s的相邻子数组
template
void MergePass(Type x[],Type y[],int s,int n)
{
int i=0;
while(i+2*s-1
{
Merge(x,y,i,i+s-1,i+2*s-1); //合并大小为s的相邻2段子数组
i+=2*s;
}
if(i+s
Merge(x,y,i,i+s-1,n-1);
else //剩下的元素个数m满足:m
for(int j=i;j<=n-1;j++)
y[j]=x[j];
}
template
void Merge(Type a[],Type b[],int left,int mid,int right)
{
int i=left;
int j=mid+1;
int k=left;
while(i<=mid && j<=right)
{
if(a[i]