把一个任务,分成形式和原任务相同,但规模更小的几个部分任务,分别完成,或只需要选一部完成。然后再处理这几个部分的结果,从而实现整个任务的完成。
分治典型应用 归并排序
① 把前一半排序
②把后一半排序
③把两半归并到一个新的有序数组,然后再拷贝回原数组
时间复杂度O(nlogn)
#include <iostream>
using namespace std;
int a[10] = { 13, 27, 19, 2, 8, 12, 2, 8, 30, 89 };
int b[10];
// 将数组a的局部a[s,m]和a[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回a[s,e]
void Merge(int a[],int s,int m,int e,int tmp[]){
int pb = 0;
int p1=s,p2=m+1;
while(p1 <= m && p2 <= e) {
if(a[p1] < a[p2])
tmp[pb++] = a[p1++];
else
tmp[pb++] = a[p2++];
}
while(p1<=m){
tmp[pb++] = a[p1++];
}
while(p2<=e){
tmp[pb++] = a[p2++];
}
for(int i=0;i<e-s+1;++i) {
a[s+i] = tmp[i];
}
}
void MergeSort(int a[],int s,int e,int tmp[]) {
if(s<e){
int m = s + (e-s)/2;
MergeSort(a,s,m,tmp);
MergeSort(a,m+1,e,tmp);
Merge(a,s,m,e,tmp);
}
}
int main() {
int size = sizeof(a) / sizeof(int);
MergeSort(a,0,size-1,b);
for(int i = 0;i < size; ++i)
cout << a[i] << ",";
cout << endl;
return 0;
}
分治典型应用 快速排序
①设k=a[0],将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边,和k相等的,在k左右出现均可。
②把k左边的快速排序
③把k右边的快速排序