尋找數組中第k小的元素---算法設計與分析的課堂記錄

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

const int maxN=10010;
int b[maxN];
int M[maxN];//儲存中項 
int A1[maxN];
int A2[maxN];
int A3[maxN];

//函數實現的功能是可以返回int數組中第k小的元素
int select(int a[maxN],int low,int high,int k)
{
	int p=high-low+1;
	if(p<44)//如果元素個數小於44個,那麼以下的算法就沒有必要,因爲時間複雜度反而更高 
	{
		sort(a,a+p);
		return a[k];
	}
	else
	{
		int q=p/5;//五個爲一組,組內分別排序 
		int x=q/2+1;
		for(int i=0;i<q;i++)
		{
			sort(a+5*i,a+4+5*i);
			M[i]=a[2+5*i];
		}
		int mm=select(M,0,q-1,ceil(q/2));//取每個組的中間項再取中間項,並且依據這個中間項分組(三個組,大於,小於,等於) 
		int a1=0,a2=0,a3=0;
		for(int i=0;i<=high;i++)
		{
			if(a[i]<mm)
			{
				A1[a1]=a[i];
				a1++;
			}
			else if(a[i]==mm)
			{
				A2[a2]=a[i];
				a2++;
			}
			else
			{
				A3[a3]=a[i];
				a3++;
			}
		}
		//那麼很顯然,k就在三個分組之間了 
		if(a1>=k) return select(A1,0,a1-1,k);
		else if(a1+a2>=k) return mm;
		else if(a1+a2<k) return select(A3,0,a3-1,k-a1-a2);
		else return -1;
	}
}

int main()
{
	freopen("尋找第.txt","r",stdin);
	for(int i=0;i<50;i++)
	{
		cin>>b[i];
	}
	int ans=select(b,0,49,44);
	cout<<ans;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章