#include<iostream> //算法导论第九章
#include<bitset>
#include<ctime>
using namespace std;
template <size_t UpperBound> class Urand{ //生成随机数
bitset<UpperBound> used;
public:
Urand(){ srand(time(0)); }
double operator() ();
};
template<size_t UpperBound>
inline double Urand<UpperBound>::operator()()
{
if(used.count() == UpperBound)
used.reset();
size_t newval;
while(used[newval = rand() % UpperBound])
;
used[newval] = true;
return newval*0.1;
}
int partition( double darr[], int p, int q) //划分
{
int groupnum = (q-p+1)/5;
int lastgroupnum = (q-p+1)-groupnum*5;
int num = (lastgroupnum==0) ? groupnum : groupnum+1;
double *Mid = new double[num]; //中位数
int *Marr = new int[num]; //中位数标志位
int i = 0; //循环标志位
int j = 0;
int h = 0;
int k = 0;
int w = 0;
int y = 0;
int z = 0;
for( i=0; i<groupnum; i++)
{
for( j=i*5+1+p; j<i*5+5+p; j++)
{
double indexOne = darr[j];
if( darr[j-1]> indexOne )
{
for( h = j-1; darr[h]>indexOne&&h>=i*5; h--)
{
darr[h+1]=darr[h];
}
darr[h+1]=indexOne;
}
}
Mid[i] = darr[(i*5+p+i*5+4+p)/2];
Marr[i] = (i*5+p+i*5+4+p)/2; //记住标志
}
if( lastgroupnum != 0)
{
for( k=groupnum*5+1+p; k<groupnum*5+lastgroupnum+p; k++)
{
double indexTwo = darr[k];
if( darr[k-1]>indexTwo )
{
for( w=k-1; darr[w]>indexTwo&&w>=groupnum*5; w--)
{
darr[w+1]=darr[w];
}
darr[w+1]=indexTwo;
}
}
Mid[groupnum] = darr[(groupnum*5+p+groupnum*5+lastgroupnum+p)/2];
Marr[groupnum] = (groupnum*5+p+groupnum*5+lastgroupnum+p)/2; //记住标志位
}
groupnum = ( lastgroupnum==0 ) ? groupnum : groupnum+1;
for( y=1; y<groupnum; y++) //中位数排序
{
double indexThree = Mid[y];
int temp = Marr[y];
if( Mid[y-1]>indexThree )
{
for( z=y-1; Mid[z]>indexThree&&z>=0; z-- )
{
Mid[z+1]=Mid[z];
Marr[z+1]=Marr[z];
}
Mid[z+1]=indexThree;
Marr[z+1]=temp;
}
}
double dtemp = darr[Marr[groupnum/2]];
darr[Marr[groupnum/2]] = darr[p];
darr[p] = dtemp;
double x = darr[p];
int start = p;
for( int r=p+1; r<=q; r++)
{
if( darr[r]<=x )
{
start++;
swap(darr[start], darr[r]);
}
}
swap(darr[start], darr[p]);
return start;
}
double SELECT( double dArr[], int p, int q, int i) //select函数
{
if( p==q )
{
return dArr[p];
}
int r = partition( dArr, p, q);
int k = r-p+1;
if( i==k )
{
return dArr[r];
}
else if( i<k )
{
return SELECT( dArr, p, r-1, i);
}
else
{
return SELECT( dArr, r+1, q, i-k);
}
}
int main()
{
Urand<23> u;
double darr[23] = { 0.0 };
for( int i=0; i<23; i++)
{
darr[i]=u();
}
cout<<SELECT(darr, 0, 22, 11)<<endl;
return 0;
}