一.分治法
1. 定义 将原问题分解成两个或者更多的相似的子问题,再用同样的方法分解子问题,直到子问题可以轻松求解,原问题的解就是子问题解的集合。
2.步骤 分解:分解原问题为若干个子问题。
解决:求解子问题,递归的求解子问题。
归并:子问题的解的集合就是原问题的解。
二.归并排序
1. 算法思想:遵循分治法思想,首先分解原问题,将待排序的n个元素的序列分解成两个具有n/2个元素的子序列。然后使用归并并排序递归地排序两个子序列。最后合并两个已经排序的子序列得到已排序的原问题的解。
2. 算法过程:归并排序中的关键步骤在于合并两个已排序的序列,我们需要调用一个辅助过程MERGE(A,p,q,r)来完成合并过程,其中A表示数组,p、q、r都是数组下标,其中A[p…q]和A[q+1…r]代表已排序的两个序列。
关于MERGE(A,p,q,r)函数的伪代码如下:
MERGE(A,p,q,r)
1. n1=q-p+1;
2. n2=r-q;
3. int B[1...n1+1],C[1...n2+1];//定义两个辅助数组
4. for i=1 to n1 do
5. B[i]=A[i+p-1];
6. for j=1 to n2 do
7. C[j]=A[j+q];
8. B[n1+1]=∞,C[n2+1]=∞;//哨兵作用
9. i=1,j=1;
10. for k=p to r
11. if(B[i]>C[j])
12. A[k]=C[j];
13. j++;
14. else
15. A[k]=B[i];
16. i++;
然后是归并排序的伪代码:
MERGE-SORT(A,p,r)
1.if p<r
2. q=(p+q)/2;
3. MERGE-SORT(A,p,q);
4. MERGE-SORT(A,q+1,r);
5. MERGE(A,p,q,r);
测试:
#include <iostream>
#define INF 10000000
using namespace std;
void Merge(int *A,int p,int q,int r)
{
int n1=q-p+1;
int n2=r-q;
int* B = new int[n1+1];
int* C = new int[n2+1];
for(int i=0;i<n1;i++)
{
B[i]=A[i+p];
}
for(int i=0;i<n2;i++)
{
C[i]=A[i+q+1];
}
B[n1]=INF;
C[n2]=INF;
int i=0,j=0;
for(int k=p;k<=r;k++)
{
if(B[i]>C[j])
{
A[k]=C[j];
j++;
}
else
{
A[k]=B[i];
i++;
}
}
}
void Merge_Sort(int* A,int p,int r)
{
if(p<r){
int q=(p+r)/2;
Merge_Sort(A,p,q);
Merge_Sort(A,q+1,r);
Merge(A,p,q,r);
}
}
int main()
{
int A[5]={1,4,7,2,5};
Merge_Sort(A,0,4);
for(int i=0;i<5;i++)
{
cout<<A[i]<<endl;
}
return 0;
}
时间复杂度:O(nlogn)