一,分治法按以下步骤工作的:
1.将问题的实例划分为同一个问题的几个较小的实例,最好拥有同样的规模
2.对这些较小的实例求解(一般使用递归方法,但在问题规模足够小的时候,也会用其他方法)
3.如果必要的话,合并这些较小问题的解,以得到原始问题的解。
举个例子说明下:比如计算n个数字的和。如果n>1,我们可以把该问题分解为它的两个实例:计算前n/2个数字的和以及计算后n/2个数字的和。一旦这两个和都被计算出来了(通过递归应用上述方法),我们就可以把这两个和相加,这样就得到原始问题的答案。
二,分治法的应用:
1.合并排序是成功应用分治技术的一个完美的例子。对于一个需要排序的数组A[n],合并排序把它一分为二,并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组。
#include<iostream>using namespace std;
const int SIZE = 100;
int arr[SIZE];
//排序数组arr[fir:end]
void mergeSort(int fir,int end){
//当子序列就只有一个元素的时候就弹出
if(fir==end)return;
//分治
int mid = (fir+end)/2;
mergeSort(fir,mid);
mergeSort(mid+1,end);
//合并
int tempArr[SIZE];
int i;
int fir1=fir,fir2=mid+1;
for( i=fir;i<=end;i++){
if(fir1>mid)
tempArr[i]=arr[fir2++];
else if(fir2>end)
tempArr[i]=arr[fir1++];
else if(arr[fir1]>arr[fir2])
tempArr[i]=arr[fir2++];
else
tempArr[i]=arr[fir1++];
}
for( i=fir;i<=end;i++)
arr[i]=tempArr[i];
}
int main(){
//测试
int n;cin>>n;
for(int i=0;i<n;i++)cin>>arr[i];
mergeSort(0,n-1);
for(int j=0;j<n;j++)cout<<arr[j]<<" ";
cout<<endl;
return 0;
}
2.快速排序是另一种基于分治技术的重要排序算法。不像合并排序是按照元素在数组中的位置对它们进行划分,快速排序按照元素的值对它们进行划分。以下是快排的实现:
#include <iostream>using namespace std;
int a[1000],n;
int partition(int fir,int end)
{
int i=fir,j=end;
int temp=a[fir];
while(i!=j)
{
while(a[j]>temp&&j>i)
j--;
if(j>i)
a[i++]=a[j];
while(a[i]<temp&&j>i)
i++;
if(j>i)
a[j--]=a[i];
}
a[i]=temp;
return i;
}
void quickSort(int low,int high)
{
if(low<high)
{
int i=partition(low,high);
quickSort(low,i-1);
quickSort(i+1,high);
}
}
int main()
{
int i;
cin>>n;
for(i=0;i<n;i++)
cin>>a[i];
quickSort(0,n-1);
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
分治法在很多算法中都有用到,以上两个例子只是比较典型的应用。算法中的方法很多,本人觉的学习算法比较有用的方法就是,了解某种方法以后,最去做有关这种方法的算法或看相关的算法题来加深理解。不断学习中,加油!