第一篇归并排序就是一种分治法的思想,通过递归调用自身函数将原问题划分为其子问题,再求解子问题,然后将子问题合并的过程。
例如有序列{5,2,4,7,6,9,1,0},第一次调用划分为{5,2,4,7}和{6,9,1,0}两个堆,第二次调用划分为{5,2},{4,7},{6,9},{1,0}4个堆,第三次调用划分为{5},{2},{4},{7},{6},{9},{1},{0},到这一步划分结束,即结束的标志就是子序列只有1个元素,可以这样理解,当子序列只有一个元素时,我们认为是有序的,然后做合并操作,这样循环调用。
下边是合并操作的代码:
void Merge(int A[],int p,int q,int r)
{
int n1=q-p+1;
int n2=r-q;
int L[n1],R[n2];
int i,j,k;
for(i=p;i<n1;++i)
{
L[i]=A[p+i];
}
for(j=q+1;j<n2;++j)
{
R[j]=A[q+j+1];
}
i=p;
j=q+1;
k=0;
while(i<n1 && j<n2)
{
if(L[i]<=R[j])
{
A[k]=L[i];
i++;
k++;
}
else
{
A[k]=R[j];
j++;
k++;
}
}
while(j<n2)
{
A[k]=R[j];
k++;
j++;
}
while(i<n1)
{
A[k]=L[i];
k++;
i++;
}
}
时间复杂度为O(n)。下边是划分子序列的函数
void Merge_sort(int A[],int p,int r)
{
int q;
if(p<r)
{
q=(p+r)/2;
Merge_sort(A,p,q);
Merge_sort(A,q+1,r);
Merge(A,p,q,r);
}
}
里面的条件块是当子序列元素数目大于1时划分,等于1时结束。
完整源码
#include <iostream>
using namespace std;
void Merge(int A[],int p,int q,int r);
void Merge_sort(int A[],int p, int r);
int main()
{
int A[8]={8,7,6,5,4,3,2,1};
int p=0,r=7;
Merge_sort(A,p,r);
for(int counter=0;counter<=r;++counter)
cout<<A[counter]<<endl;
return 0;
}
void Merge(int A[],int p,int q,int r)
{
int n1=q-p+1;
int n2=r-q;
int L[n1],R[n2];
int i,j,k;
for(i=p;i<n1;++i)
{
L[i]=A[p+i];
}
for(j=q+1;j<n2;++j)
{
R[j]=A[q+j+1];
}
i=p;
j=q+1;
k=0;
while(i<n1 && j<n2)
{
if(L[i]<=R[j])
{
A[k]=L[i];
i++;
k++;
}
else
{
A[k]=R[j];
j++;
k++;
}
}
while(j<n2)
{
A[k]=R[j];
k++;
j++;
}
while(i<n1)
{
A[k]=L[i];
k++;
i++;
}
}
void Merge_sort(int A[],int p,int r)
{
int q;
if(p<r)
{
q=(p+r)/2;
Merge_sort(A,p,q);
Merge_sort(A,q+1,r);
Merge(A,p,q,r);
}
}