小田田的算法笔记——分治

分治

|| 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 setS
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

猜你喜欢

转载自blog.csdn.net/tian__si/article/details/106170740