归并排序:
基本思想:将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再将子序列合并为整体有序序列。(2-路归并:将两个有序子序列合并为整体有序的序列)
2-路归并算法描述:
① 申请一个大小为两子序列之和的空间(取名:合并空间),用以存放合并后的有序序列。
② 设定两指向子序列起始位置的标签,以及一指向合并空间起始位置的标签。
③ 比较两子序列标签所指元素,将较小者装入合并空间,并将指向较小者的标签后移。
④ 合并空间标签后移。
⑤ 重复③直至某子序列标签(首次)超出子序列列尾(循环条件破坏)。
⑥ 将(循环条件为被破坏的)另一子序列中剩下元素直接装入合并空间。
2-路归并算法实现:
//2-路归并排序
voidMerge(RecType SR[],RecType TR[],int t,int m,int n)
{
//将有序子序列SR[t...m]和SR[m+1...n]合并到有序序列TR[t...n](合并空间)
//步骤①:申请合并空间为TR[t…n]
int i,j,k;
//步骤②:设定的起始位置标签分别为:i=t,j=m+1,k=t
for(j=m+1,i=t,k=t;i<=m&&j<=n;k++){//步骤④:合并空间标签后移(k++)
if(SR[i].key<=SR[j].key)//步骤③:比较两子序列标签所指元素
TR[k]=SR[i++];//步骤③:将较小者装入合并空间,并将指向较小者的标签后移
else
TR[k]=SR[j++];
}//步骤⑤:重复步骤③,直至某子序列标签(首次)超出子序列列尾(此时:i>m||j>n)循环条件破坏
while(i<=m) TR[k++]=SR[i++];//步骤⑥:将(循环条件未被破坏的)另一子序列中剩下元素装入合并空间
while(j<=n) TR[k++]=SR[j++];
}
归并排序基本思想:
将一个SR[m…n]的无序序列拆成SR[m…(m+n)/2],和SR[(m+n)/2+1…n]两个子序列,然后在两个无序子序列内部再按上述方法拆分。直至相邻两子序列中都仅有一个元素。此时因为两子序列都仅有一元素故两子序均为有序序列。再调用2-路归并算法将由一无序序列拆分成的两子(有序)序列合并成一有序序列。按照相同方法继续合并(有序)序列直至全部元素合并成一有序序列。
归并排序实现:
voidMergeSort(RecType SR[],RecType TR[],int m,int n)
{
//对SR[m...n]进行排序然后装入TR[]数组
RecType TempR[MAX];//用来暂储归并排序的中间排序后结果的辅助空间
int mid;
if(m==n)//递归条件破坏(已拆分成只有一个元素的序列)
TR[m]=SR[m];//实际上是返回给TempR数组
else{
mid=(m+n)/2;//将无序序列拆分
MergeSort(SR,TempR,m,mid);//无序子序列内部继续拆分
MergeSort(SR,TempR,mid+1,n);//无序子序列内部继续拆分
//首次Merge(TempR,TR,0,0,1)
Merge(TempR,TR,m,mid,n);//调用2-路归并算法将由一无序序列拆分成的两子(有序)序列合并成一有序序列
}
}
其参数传递:
示例: 对 29 35 20 4743 46 41 38 29 30 39 进行归并排序
拆分过程:
拆分合并流程:
代码实现:
#include<iostream>
using namespace std;
#define MAX 50
typedef int KeyType;
typedef struct{
KeyType key;//关键字
//其他数据
}RecType;
typedef RecType SeqRecList[MAX];
void Merge(RecType SR[],RecType TR[],int t,int m,int n);
void MergeSort(RecType SR[],RecType TR[],int m,int n);
int main()
{
int i;
SeqRecList R,M;
R[0].key=29;
R[1].key=35;
R[2].key=20;
R[3].key=47;
R[4].key=43;
R[5].key=46;
R[6].key=41;
R[7].key=38;
R[8].key=29;
R[9].key=30;
R[10].key=39;
MergeSort(R,M,0,10);
for(i=0;i<11;i++)
cout<<M[i].key<<" ";
cout<<endl;
}
void Merge(RecType SR[],RecType TR[],int t,int m,int n)
{
int i,j,k;
for(j=m+1,i=t,k=t;i<=m&&j<=n;k++){
if(SR[i].key<=SR[j].key)
TR[k]=SR[i++];
else
TR[k]=SR[j++];
}
while(i<=m) TR[k++]=SR[i++];
while(j<=n) TR[k++]=SR[j++];
}
void MergeSort(RecType SR[],RecType TR[],int m,int n)
{
RecType TempR[MAX];
int mid;
if(m==n)
TR[m]=SR[m];
else{
mid=(m+n)/2;
MergeSort(SR,TempR,m,mid);
MergeSort(SR,TempR,mid+1,n);
Merge(TempR,TR,m,mid,n);
}
}
编译执行: