/*算法导论第九章,中位数和顺序统计。
9.1 第i个顺序统计的意思是集合中第i个小的元素,对于n个数,当为奇数的时候中位数就是指第(n+1)/2的那个数,当是偶数的时候就是有两个
中位数,包括上中位数(n+1)/2(向上取整),以及(n+1)/2(向下取整),对于n个数中求最大值或者最小值一般情况下的话,需要的是n-1个次比较,
对于求最大也求最小的话,需要比较的次数是2(n-1)次;但是也有一种方法把比较的次数减少到3*(n/2)(向下取整),具体方法是:首先是一对数进行对比
求出数中最大和最小的数字,之后对余下的数字,两两进行输入,首先进行相互比较,大的和之前的大的比较,小的和小的比较,那么对于n为奇数以及为偶数相应
就对于最初的最大和最小的数字进行初始化,当为奇数的时候就是第一个赋值为最大以及最小,为偶数的时候就首两个进行赋值,如此进行计算的话,奇数的时候进行
比较的次数是3*n/2(向上取整),当为偶数的时候比较次数就是:3*(n-2)/2+1(向上取整),具体代码如下
*/
#include <iostream>
#include <algorithm>
using namespace std;
#define length 10
void print(int *A)//打印
{
int i;
for (i=0;i<length;++i)
{
cout<<A[i]<<" ";
}
cout<<endl;
}
/***************最初版本的求最大最小*****************/
pair<int,int> min_max(int *A)
{
int min=0xfffffff;
int max=0;
int i;
for (i=0;i<length;++i)
{
if (min>A[i])
{
min=A[i];
}
if(max<A[i])
{
max=A[i];
}
}//比较2次;
pair<int,int> p(min,max);
return p;
}
/**************使用新的比较方法(3*n)/2次完成*********************/
pair<int,int> max_min(int *A)
{
int max,min,i;
if((length)%2!=0)
{
min=max=A[0];
i=1;
}else
{
min=A[0];
max=A[1];
if(A[0]>=A[1])
{
min=A[1];
max=A[0];
}
i=2;
}
for (;i<length;i+=2)
{
if(A[i]>=A[i+1])
{
if(A[i]>max)
{
max=A[i];
}
if(A[i+1]<min)
{
min=A[i+1];
}
}else
{
if(A[i]<min)
{
min=A[i];
}
if(A[i+1]>max)
{
max=A[i+1];
}
}
}
/*
参考师姐的做法:缩减代码数;学习下;搞ACM的果然不是盖的。
for(i;i<length;i+=2)
{
int a=min(A[i],A[i+1]);
int b=A[i]+A[i+1]-a;
if(a<min)
{
min=a;
}
if(b>max)
{
max=b;
}
}
*/
pair<int,int> p(max,min);
return p;
}
/*****************期望线性时间选择******************************/
//选择第i小的,书上说,一般情况下选择问题比最小值问题复杂,但是这里给出的方法就是一种可以在线性时间内解决选择最小的;
int partion(int * A,int p,int r)
{
int x=A[r];
int i=p-1;
for (int j=p;j<r;++j)
{
if(A[j]<=x)
{
swap(A[++i],A[j]);
}
}
swap(A[i+1],A[r]);
return i+1;
}
int rand_partion(int *A,int p,int r)
{
int i=rand()%(r-p+1)+p;
swap(A[r],A[i]);
return partion(A,p,r);
}
int randselect(int * A,int p,int r,int i)
{
if(p==r)
return A[p];
int q=rand_partion(A,p,r);
int k=q-p+1;
if(k==i)//第i个
return A[q];
else
if(i<k)
return randselect(A,p,q-1,i);//如果第i个数比k小
else
return randselect(A,q+1,r,i-k);
}
int main()
{
int num;
int A[length];
int pos;
for (num=0;num<length;++num)
{
cin>>A[num];
}
print(A);
cout<<min_max(A).first<<" "<<min_max(A).second<<endl;
cout<<"----------------"<<endl;
cout<<max_min(A).first<<" "<<max_min(A).second<<endl;
cout<<"----------------"<<endl;
cin>>pos;
cout<<randselect(A,0,length-1,pos)<<endl;
return 0;
}
算法导论复习第九章
最新推荐文章于 2020-04-23 21:58:49 发布