1. 分治策略的基本思想算法
1.1例子数组
二分查找:在一个排好序的数组T[1..n]中查找x,若是x在T中,输出x在T中的下标j;若是x不在T中,输出j=0。使用下述二分查找算法。ide
算法1.1 BinarySearch(T,l,r,x)spa
输入:数组T,下标从l到r;数x设计
输出:jorm
l←1;r←n排序
while l≤r do递归
m←(l+r)/2ci
if T[m]=x then return xio
else if T[m]>x then r←m-1;
else l←m+1
return 0
经过x与数组T中元素的1次比较,T中须要检索的范围至少减半,所以检索次数W(n)知足递推方程:W(n)=W(n/2)+1,w(1)=1;解出W(n)=logn+1
二分归并排序:将被排序的数组分红两个相等的子数组,而后使用一样的方法对子数组排序,最后将两个排好序的子数组归并成一个数组。
算法1.2 MergeSort(A,p,r)
输入:数组A[p..r]
输出:按照递增顺序排好的数组A
if p<r then
q←(p+r)/2;
MergeSort(A,p,q)
MergeSort(A,q+1,r)
Merge(A,p,q,r)
算法1.3 Merge(A,p,q,r)
输入:按照递增顺序排好序的数组A[p..q]与A[q+1,r]
输出:将A[p..q]复制到B[1..x],将A[q+1,r]复制到C[1..y]
i←1,j←1,k←p
while i≤x and j≤y do
if B[i]≤C[j]
A[k]←B[j]
i←i+1;
k←k+1
if i>x then 将C[j..y]复制到A[k..r]
else 将B[i..x]复制到A[k..r]
W(n)知足递归方程:W(n)=2W(n/2)+n-1,W(1)=0,解得W(n)=O(nlogn)
上面两个算法就是用分治策略设计的算法。它们的共同特色是:将规模为n的原问题归约成规模减半的子问题(能够是一个字问题,也能够是多个字问题)。分别求解每一个字问题,而后把字问题的解进行综合,从而获得原问题的解。
2.分治算法的通常性描述
把上面的思想加以归纳,能够获得分治算法的通常描述。高P是待求解的问题,|P|表明该问题的输入规模,通常的分治算法Divide-and-Conquer的伪码描述以下:
算法2.1 Divide-and-Conquer (P)
if |P|≤c then S(P)
divide P into P1,P2,…,Pk
for i=1 to k do
yi=Divide-and-Conquer (Pi)
return Merge(y1,y2,…,yk)
上述伪码说明:若是问题的规模不超过c(在上述二分检索和二分归并算法中c=1),算法中止递归,直接求解P,S(P)就表明直接求解的过程;不然,将P归约成k个彼此独立的子问题P1,P2,…,Pk,而后递归地依次求解这此子问题,获得解y1,y2,…,yk,最后将这k个解归并获得原问题的解,Merge表明归并子问题的解的过程。
分治算法一般是递归算法,这种算法的时间复杂度分析一般须要求解递推方程。若是原问题的输入规模是n,根据上面的伪码,分治算法时间复杂度的递推方程和通常形式是:
W(n)=W(|P1|)+W(|P2|)+…+W(|Pk|)+f(n),W(c)=C;.
上面的C表明直接求解规模为c的子问题的工做量,而f(n)表明将原问题归约为若干个子问题以及将子问题的解综合为原问题的解所须要的工做量。
3. 分治算法的分析技术
在分治算法中常见的递推方程有下面两类:
若是归约后的子问题的规模比原问题呈现常数量级的减小,就会获得第一类递推方程。第一类方程能够用迭代、换元、递归树、尝试等方法求解。
第二类递推方程反映的是相似于二分检索和二分归并排序算法的分治算法,在均衡划分的状况下,a 表明归约后的子问题个数,b表明子问题规模减小的倍数,d(n)表示归约过程和综合解过程的总工做量。这两类方程的求解算法可使用迭代法、递归树和主定理等,使用大O记号表示解,有以下几种常见的方式:
当d(n)为常数时,若是a=1,那么符合主定理的第二种状况,因而T(n)=O(logn);若是a≠1,不是常数,属于主定理第一种状况,T(n)=O(
)。
当d(n)=cn时,若是a>b,对应主定理第一种状况,方程的解是=O();若是a=b,对就主定理第二种状况,方程的解是O(nlogn);若是a<b,对应主定理的第三种状况,方程的解是O(f(n))=O(n)。
利用上述结果,直接能够获得二分检索算法的时间复杂度为O(logn),二分归并排序算法的时间复杂度为O(nlogn)。