演算法筆記04--分治法之尋找最大最小元素

兔美醬xz發表於2014-11-25

顧名思義,“分治”名字本身就已經給出了一種強有力的演算法設計技術,它可以用來解決各類問題。在它最簡單的形式裡,一個分治演算法把問題例項劃分成若干子例項(多數情況是分成兩個),並分別遞迴地解決每個子例項,然後把這些子例項的解組合起來,得到原問題例項的解。

尋找最大最小解

一種直接的演算法如下所示,它返回一個數對(x,y),其中x是最小值,y是最大值

1 x<-A[1] ; y<-A[1]

2 for i <- 2 to n

3        if A[i] < x then x <- A[i]

4        if A[i] > y then y <- A[i]

5 end for

6 return (x,y)  

很顯然執行次數為2*n-2

下面使用分治策略。

思路:

將陣列分割成兩半子例項,遞迴的在每一個子例項中找到最大值和最小值,然後將兩個子例項的最小值中的最小值和最大值中的最大值返回。

時間複雜度:

C(n) = 1, n=2

C(n) = 2*C(n/2) + 2 , n>2

假設n = 2^k , k = log n

C(n) = 2*C(n/2) +2 

        = 2*(2*C(n/4) +2 ) + 2

.....

        = 2^(k-1)*C(n/2^(k-1)) + 2^(k-1) + 2^(k-2) + + 2^2 + 2

= 2^(k-1)*(C(2)) + 2^k - 2

= 3n/2 - 2

程式碼:

#include<iostream>
using namespace std;


int A[8] = {5,-3,2,7,10,1,2,-8};

struct minmaxV
{
	int maxV;
	int minV;
};


minmaxV minmax(int low , int high)
{
	minmaxV temp,temp1,temp2,temp3;
	if(high - low==1)
	{
		if(A[low]<A[high])
		{	
			temp.minV = A[low];
			temp.maxV = A[high];
		}
		else
		{
			temp.minV = A[high];
			temp.maxV = A[low];
		}
			return temp;
	}
	else
	{
		int mid = (low + high) /2 ;
		temp1 = minmax(low,mid);
		temp2 = minmax(mid+1 , high);
		temp3.minV = (temp1.minV<temp2.minV)?temp1.minV:temp2.minV;
		temp3.maxV = (temp1.maxV>temp2.maxV)?temp1.maxV:temp2.maxV;
		return temp3;
	}
}

int main()
{
	minmaxV showMinMax;
	showMinMax =  minmax(0,7);
	cout<<"min: "<<showMinMax.minV<<"  max: "<<showMinMax.maxV<<endl;
	return 1;
}



相關文章