算法设计与分析复习-分治法算法描述

//分治:划分、解子问题、组合 
//每个递归算法均可以转换为迭代算法 
#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 
 

你可能感兴趣的:(算法设计与分析复习-分治法算法描述)