The Program of Algorithms ------- Diveide and Conquer ---- Randomized-Select

Randomized-Select:

Question:Given n elements in array, find the i-th smallest element.

Navie Algorithm: Sort A and return A[i]. Best Time cost will be O(nlgn).


Divide: Using the Quick Sort Randomized-Partition, return the pivot position k-th, this is the pivot num final position.

Conquer: There are three cases. 

      case1: i==k return A[q]. (k!=pivot pos "q" in A; while, k=(q-p+1))

      case2: i<k means the i-th element is in the left part, so recursively find in the left part for the i-th elem.

      case3: i>k means the i-th element is in the right part, recursively find in the right part for the (i-k)-th elem.


Realize the algorithm using CPP as follow:

#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
namespace MERGE{
	const int INFINITE=0xFFFFFFFF;
	void Merge(int* Arr,int p,int q,int r){//Combine
		int len_l=q-p+1;
		int len_r=r-q;
		int *LeftArr=new int[len_l+1];
		int *RightArr=new int[len_l+1];
		int i,j;
		for(i=0;i<len_l;i++){
			LeftArr[i]=Arr[p+i];
		}
		for(j=0;j<len_r;j++){
			RightArr[j]=Arr[q+j+1];
		}
		LeftArr[i]=INFINITE;
		RightArr[j]=INFINITE;

		int k_l=0,k_r=0,k=0;
		while(LeftArr[k_l]!=INFINITE&&RightArr[k_r]!=INFINITE){
			if(LeftArr[k_l]<RightArr[k_r]){
				Arr[p+k]=LeftArr[k_l];
				k_l++;
			}else{
				Arr[p+k]=RightArr[k_r];
				k_r++;
			}
			k++;
		}
		while(LeftArr[k_l]!=INFINITE){
			Arr[p+k]=LeftArr[k_l];
			k_l++;
			k++;
		}
		while(RightArr[k_r]!=INFINITE){
			Arr[p+k]=RightArr[k_r];
			k_r++;
			k++;
		}
		delete LeftArr;
		delete RightArr;
	}

	void MergeSort(int* Arr,int p,int r){	//Divide
		if(p<r){
			int q=(p+r)/2;
			MergeSort(Arr,p,q);
			MergeSort(Arr,q+1,r);
			Merge(Arr,p,q,r);
		}
	}
}
namespace SELECT_ALG{
	int Randomized_PartitionArr(int* Arr,int p,int q){
		srand((int)time(0));
		int size=q-p+1;
		int index=rand()%(size)+p;
		int pivot=Arr[index];
		Arr[index]=Arr[p];
		Arr[p]=pivot;
		int i=p;

		for(int j=p+1;j<p+size;j++){
			if(Arr[j]<=pivot){
				i++;
				int tmp=Arr[i];
				Arr[i]=Arr[j];
				Arr[j]=tmp;
			}
		}	

		int tmp=Arr[i];
		Arr[i]=Arr[p];
		Arr[p]=tmp;
		return i;
	}

	int Randomized_Select(int A[],int p,int r,int i){//Find the i-th number in A whose index between p and r
		if(p==r){
			return A[p];
		}
		int q=Randomized_PartitionArr(A,p,r);
		int k=q-p+1;
		if(i==k){
			return A[q];
		}else if(i<k){
			return Randomized_Select(A,p,q-1,i);
		}else{
			return Randomized_Select(A,q+1,r,i-k);
		}

	}
}

using namespace SELECT_ALG;
using namespace MERGE;
int main(){
	int index=5;
	int A[20]={34,2,3,45,20,10,7,14,21,33,51,40,39,22,32,11,12,45,30,20};
	int B[20]={34,2,3,45,20,10,7,14,21,33,51,40,39,22,32,11,12,45,30,20};
	
	cout<<"The "<<index<<"th num is:"<<Randomized_Select(A,0,19,index)<<endl;

	MergeSort(B,0,19);
	for(int i=0;i<20;i++){
		cout<<setw(3)<<i+1;
	}
	cout<<endl;
	for(int i=0;i<20;i++){
		cout<<setw(3)<<B[i];
	}
	cout<<endl;
	return 0;
}

Analysis the Expected Time:

-- let T(n) be the random variable for running time of Randomized_Select on input of size n, assuming random numbers are independent.

-- define: indicator random variable. X_k for k=0 to n. 

    X_k=1 if partition gerenrate k:n-k-1 split.

    X_k=0 otherwise

    And the T(n) can be express as follow:

1.T(max{0,n-1}+Θ(n)) if 0:n-1 split

2.T(max{1,n-2}+Θ(n)) if 1:n-2 split

    T(n)= .......

n.T(max{n-1,0}+Θ(n)) if n-1:0 split

All expression above can include as the following equation:

     T(n)=∑X_k(T(max{k,n-k,1})+Θ(n));

(

Note: The recurrence is about one round partition. when k is from 0 to n, there is only one X_k equal to 1.

)

     E(T(n))=E(∑X_k(T(max{k,n-k,1})+Θ(n)))=E(X_k(T(max{k,n-k,1})+Θ(n)))=E(X_k)*E(T(max{k,n-k,1})+Θ(n)))

(

Note: last state has the condition that the X_k independet with T(max{k,n-k-1}).

This can be easy proved. As random numbers are independent. We can easily find out the current X_k has confirm before we do another partition in T(max{k,n-k-1}), so the X_k in T(max{k,n-k-1}) is independent with the X_k in the top-level.

E(X_k)=0*P(X_k=0)+1*P(X_k=1)=P(X_k=1)=1/n

)

     E(T(n))=1/n*∑E(T(max{k,n-k-1}))+1/n*Θ(n) (∑ range from 0 to n-1)

     E(T(n))=2/n*∑E(T(k))+Θ(n) (k`s range is from n/2 to n-1)

Next: Use subsititution to prove the time is O(n)

     Assume it is true for the time is Cn

     E(T(n))=2/n*∑Ck+Θ(n)  and ∑Ck<=3/8n^2

     So, E(T(n))<=Cn-(1/4C*n-Θ(n))<=Cn   (When C is sufficient)

Now we can say, the expected running time is Θ(n).

But the worst-case, the time complexity will be Θ(n^2).


We may use some method to substitute Randomize the pivot to guarantee the worst-case in linear time.

It will be like this:

1.Divide the n elements in to n/5 group each group has 5 elements.

2.Find the median of each group.

3.Find the median of the medians as the pivot.

4.Do the patition and other part as the same with Randomized-Select.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值