//分治:划分、解子问题、组合
//每个递归算法均可以转换为迭代算法
#include <stdio.h>
#include <stdlib.h>
//寻找最大最小元素,最大比较次数 3*N/2 - 2
minmax(low,high)
if(high - low = 1)
if(arr[low] < arr[high])
return (arr[low],arr[high])
else
return (arr[high],arr[low])
end if
else
mid = (low+high)/2
(x1,y1) = minmax(low,mid)
(x2,y2) = minmax(mid+1,high)
x = min(x1,x2)
y = max(y1,y2)
return (x,y)
end if
//寻找第k小元素或中项 O(NlogN)
//每个递归调用划分步骤中,丢弃元素的固定部分,问题规模不断减小
select (A,low,high,k)
p = high - low + 1
if(p < 44)
Sort(A)
return A[k]
else
q = p/5;
把A分成q组,每组5个元素;若不整除,排除剩余的元素
q中的每一组单独排序,找出中项,放入集合M
mm = select(A,1,q,q/2) //找出中项集合的中项
把A分成三组:A1= {a|a<mm} A2 ={a|a=mm} A3 = {a|a > mm}
case
|A1| >= k : return select(A1,1,|A1|,k)
|A1| + |A2| >= k: return mm
|A1| + |A2| < k: return select(A3,1,|A3|,k-|A1|-|A2|)
end case
end if
//大整数乘法
//把n位大整数X 分为n/2位的两部分 X1,X2,则X = X1*2^(n/2) + X2 幂运算可以做移位
//X*Y = X1*Y1*2^n + ((X1+X2)(Y1+Y2))-X1*Y1 - X2*Y2)*2^(n/2)+X2*Y2 只需要3次n/2规模的乘法和6次加减运算
//T(n) = 3T(n/2)+bn O(n^1.59)
//矩阵乘法
//传统的O(n^3):乘法:n^3 加法:n^3-n^2
//优化 O(n^2.81):乘法7次、加法18次: T(N) = 7*T(N/2) + 18*(N/2)^2a
/*增加减法以减少乘法:设置7个d,根据A,B的子矩阵计算,利用d组成C
*/
//最近点对问题 O(n*log n)
输入:平面上n个点的集合S
输出:S中两点的最小距离
以x坐标递增排序S
Y = 以y坐标递增排序S
Z = cp(1,n)
cp(low,high)
if(high - low +1 <=3)
直接计算距离
else
mid = (high + low)/2
x0 = x(S[mid]) //找出x的中线
Zl = cp(low,mid)
Zr = cp(mid+1,high)
Z = min(Zl,Zr)
k = 0
//从Y中抽取T,找出那些在中线附近Z区域的点
for(i = 1~n)
if(|x(Y[i] - x0| <= Z)
k = k+1
T[k] = Y[i]
end if
end for
Z0 = 2Z
for(i = 1~k-1)
//对这些点上部的7个点比较距离
for(j = i+1 ~ min{i+7,k})
if(d[T[i],T[j]) < Z0
Z0 = d(T[i],T[j])
end for
end for
Z = min(Z,Z0)
end if
return Z
算法设计与分析复习-分治法算法描述
最新推荐文章于 2022-10-25 11:00:11 发布