提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
算法是对解决一个问题的步骤的描述,对大量的数据进行处理或者复杂操作都是不可少的。本人目前也是第一次系统的学习算法,在这里谈一下对分治算法的理解。
一、分治策略
分治步骤一般为三步:
1、将原始的问题划分为规模更小、性质相同、彼此不影响的子问题。(子问题的规模要尽可能均衡,这样算法的复杂度会好一些)
2、用递归或迭代的方法独立求解这些子问题。用递归或迭代的时候要设置终止条件,即当问题的规模足够小时,有直接的求解算法。
3、将这些子问题的解综合为原问题的解。
改进分治算法的途径:
1、减少子问题个数。
2、增加预处理。
二、分治算法描述
DIvide-and-Conquer(P)
{
if(|P|<n0) //问题的规模足够小
Adhoc(P); //算法直接求解小规模的问题
divide P into p1,p2,...,pn; //将原始问题进行划分
for(int i=1;i<=n;i++)
{
yi = Divide-and-Conquer(Pi); //递归求解子问题
}
return (Merge(y1,y2,...,yn)); //将子问题的解综合为原问题的解
}
三、用分治算法解决具体问题
1、折半查找
//用while进行查找,就不需要在改变i、j指针后进行递归
BinarySearch(T[],l.r.e) //l、r为数组T的上下界
{
i = l;j = r;
while(i<=j) //数组有元素
{
mid = (i+j) / 2; //定义中值
if(T[mid]==e)
return mid;
else if(T[mid]>e) //进行划分,要找的数据在左半部分
j = mid -1;
else //进行划分,要找的数据在右半部分
i = mid + 1;
}
return -1; //折半查找失败
}
2、二分归并排序
MergeSort(a[],l,r)
{
if(l<r) //数组有元素
{
int i = (l+r) / 2;
MergeSort(a,l,i); //划分子问题,递归解决,数组的左半部分
MergeSort(a,i+1,r); //划分子问题,递归解决,数组的右半部分
Merge(a,l,i,r); //综合解
}
}
3、最大连续子序列和问题
问题描述:给定由n个整数(可能为负整数)组成的序列a1,a2,…,an,求该序列形如的子段和的最大值。
例如:当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为20。
若将所给的序列num[1:n]分为长度相等的两段num[1:n/2]和num[n/2+1:n],分别求出这两段的最大子段和,则num[1:n]的最大子段和有三种情形:
1、num[1:n]的最大子段和与num[1:n/2]的最大子段和(leftmax)相同;
2、num[1:n]的最大子段和与num[n/2+1:n]的最大子段和(rightmax )相同;
3、num[1:n]的最大子段和为num[i,j]的最大子段和,且1<=i<=n/2,n/2+1<=j<=n。(lefta+righta)
solve(num[],l,r)
{
if(l==r)//只有一个元素
return num[l];
mid = (l+r) / 2;//一分为二
leftmax = solve(num,l,mid);//划分子问题,对左半部分递归调用,得到最大值
rightmax = solve(num,mid+1,r);//划分子问题,对右半部分递归调用,得到最大值
//对于最大子段和跨中点的情况,即情况三
lefta = num[mid];
righta = num[mid+1];
sum = 0;
for(i=mid;i>=l;i--)//跨中点的左半部分子段和
{
sum += num[i];
if(sum>lefta)
lefta = sum;
}
sum = 0;
for(i=mid+1;i<=r;i++)//跨中点的右半部分子段和
{
sum += num[i];
if(sum>righta)
righta = sum;
}
amax = lefta + righta;//相加两部分的最大值
if(leftmax>amax)
amax = leftmax;
if(rightmax>amax)
amax = rightmax;
return amax;
}
四、总结
分治三步走:
1、划分子问题。
2、独立求解子问题。
3、综合解。
分治算法的改进途径:
1、减少子问题的个数。
2、增加预处理。
子问题均衡问题:子问题规模比不变。均衡指的是比例,如原问题划分为1:9的两个子问题,再对子问题按1:9进行划分,直到最后的问题规模可以用算法直接求解为止,建立了一个递归树。
本人初学者,此文为本人对分治算法的理解。如有问题,欢迎指正,大家一起交流学习。