分治
|| minmax
在数组A[1…n]中同时寻找最大值和最小值
general method
x = A[1] , y = A[1]
for i=2 to n
if A[i]<x
then x=A[i]
if A[i]>y
then y=A[i]
end for
return (x,y)
complexity: 2(n-1)
divide and conquer???
call minmax(1...n)
process minmax(low,high)
if high-low = 1 then
if A[low]<A[high] then return(A[low],A[high])
else return(A[high],A[low])
end if
end if
mid = (low+high)/2 // divide it into two pieces
(x1,y1) = minmax(low,mid)
(x2,y2) = minmax(mid+1,high) // conquer it
x = min{x1,x2}
y = max{y1,y2}
return (x,y)
complexity: (3n)/2 - 2
analysis ???
|| binary search——simplify and conquer
Input: 非降序排列数组A[1...n]和元素x
Output: 如果 x = A[j] ,输出j;否则输出0
call binarysearch(1,n)
process binarysearch(low,high)
if low>high return 0
else
mid = (low+high)/2
if x = A[mid] return mid
else if x<A[mid] then return binarysearch(low,mid-1)
else return binarysearch(mid+1,high)
end if
complexity: O(logn)
analysis ???
|| mergesort
Input: Array A[1...n]
Output: Array A that is not in descending order
call mergesort(A,1,n)
process mergesort(A,low,high)
if low<high then
mid = (low+high)/2
mergesort(A,low,mid)
mergesort(A,mid+1,high)
MERGE(A,low,mid,high)
end if
complexity: (nlogn)/2 ~ nlogn-n+1
analysis ???
【
】
min
max
|| Looking for mid element and the K th little element
Input: A[1...n] and integer k
Output: the k th little element in A
call select(A,1,n,k)
process select(A,low,high,k)
p = high-low+1
if p<44 then sort(A) and return A[k]
q = |_ p/5_| // 将A分成q组,每组5个元素
//将 q 组中的每一组单独排序,找出中项。所有中项集合为M
mm = select(M,1,q,|—q/2—|) // mm是M的中项
A1 = {a|a<mm}
A2 = {a|a=mm}
A3 = {a|a>mm} // 将A分成三组
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
complexity: O(n)
analysis ???
【
】
|| quicksort
划分算法 ???
SPLIT
Input: A[low...high]
Output:A and pivot's new place(w)
i = low
x = A[low]
for j = low + 1 to high
if A[j] <= x then
i = i + 1
if i != j then A[i]< —>A[j]
end if
end for
A[low]< —>A[i]
w = i
return (A , w)
complexity: O(n)
整体算法???
Input: A[low...high]
Output: A in non-descending order
call quicksort(A,1,n)
process quicksort(A,low,high)
if low<high then
SPLIT(A[low...high],w)
quicksort(A,low,w-1)
quicksort(A,w+1,high)
end if
complexity: O(nlogn)
analysis ???
worst ???
average ???
|| large integer mutiplication
|| matrix multiplication
令A和B是两个n x n 的矩阵,我们希望计算它们的乘积 C = AB。如何把分治策略应用到这个问题上,从而获得一个有效的算法?
|| the problem of shortest dot pair
Input: piont set —S
Output: shortest distance
Pre:
// 以 x 坐标增序对 S 中的点排序
// Y <—以 y 坐标增序对 S 中的点排序
call: cp(1,n)
process: cp(low , high)
if high-low<=3 then //用直接方法计算 &
else
mid = |_(low+high)/2_|
x0 = x( S[mid] )
&l = cp(low , high)
&r = cp(mid+1 , high)
& = min{&1 , &r} // 计算好两侧最小距离
k=0
for i=1 to n
if |x(Y[i]) - x0| <= & then
k = k + 1
T[k] < — Y[i]
end if
end for // 从 Y 中抽取 T
&' = 2*&
for i=1 to k-1
for j=i+1 to min{i+7,k}
if d(T[i],T[j]) < &' then &' = d(T[i],T[j])
end for
end for
& = min{& , &'}
end if
return &
complexity: O(nlogn)
analysis ???
.
例题
n支球队进行循环竞标赛,每支球队都比赛过一次,已知所有的比赛结果(只有赢和输两种情况),设计一个算法,将所有球队的名字排成一个序列,使得每个比赛获胜的球队的队名都在其所赢的球队的前面。
// 本质上是一个排序算法,使用quicksort
split(A[low...high], w)
x = A[low];
i = low;
for j = i + 1 to high
if(A[j] < x)
i = i + 1;
A[j] <-> A[i];
end if
end for
A[low] <-> A[i];
w = i;
1. quicksort(A, 1, n)
process quicksort(A, low, high)
if(low < high) then
split(A[low...high], w)
quicksort(A, low, w-1);
quicksort(A, w+1, high);
end if
(1) WWWCCCHHHGGG
(2) WCWCWCHGHGHG
(3)GGGHHHCCCWWW
(4)GHGHGHCWCWCW