您的位置:首页 > 其它

中位数和顺序统计学

2010-09-05 21:28 232 查看
1 最大值和最小值

对大小为n的数组求最大值或最小值,仅需比较n-1次即可。

MinMum(A,n)
min=A[0];

for(i=1;i<n;i++)

  if(A[i]<min)

     min=A[i];

对最大值也是如此。

若同时取得最大值和最小值,按照上述方法,需比较2(n-1)次。

事实上,至多3/2n次即可同时求得最大值和最小值。成对成对的比较,对没对数先进行比较,然后另其中较大者与max比较,较小者与min比较,这样每对只需比较3次,共需3/2n次。初始化最大值最小值时还需区分偶数和奇数。

2 求第i小的元素。

类似与快速排序,利用分治法,将输入数组A[p..r]划分成两个字数组A[p..q-1]和A[q+1..r],其中一个子数组中的元素小于A[q],另一个字数组中的元素大于A[q],然后根据第i小的元素落在那个子数组中进行递归调用,伪代码如下:

Randomized_Select(A,p,r,i)

if (p==r)

   return A[p];

q=Randomized_Select(A,p,r);

k=q-p+1;

if(i==k)

   return A[q];

if(i<k)

   return Randomized_Select(A,p,q-1,i);

else

   return Randomized_Select(A,q+1,r,i-k);

示例代码如下:

 
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
void Swap(int &a,int &b)
{
int t;
t=a;
a=b;
b=t;
}
int Randomized_Partition(int *A,int p,int r)
{
int i,j;
//产生p..r之间的随机数
srand( (unsigned)time( NULL ) );
i=rand()%(r-p+1)+p;
Swap(A[i],A[r]);
int x=A[r];
j=p;
for(i=p;i<r;i++)
{
if(A[i]<x)
{
Swap(A[i],A[j]);
j++;
}
}
Swap(A[r],A[j]);
return j;
}
int Randomized_Select(int *A,int p,int r,int i)
{
if(p==r)
return A[p];
int q=Randomized_Partition(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);
}
int main()
{
int n;
cin>>n;
int *A;
A=new int
;
int i;
//srand( (unsigned)time( NULL ) );
for(i=0;i<n;i++)
{
/*A[i]=rand()%1000;
cout<<A[i]<<" "<<endl;*/
cin>>A[i];
}
int num;
cin>>num;
cout<<"第"<<num<<"个小的数是:"<<Randomized_Select(A,0,n-1,num)<<endl;
cout<<Randomized_Select(A,0,n-1,n/2+1)<<endl;
delete []A;
return 0;
}


ps:该算法最坏情况下时间复杂度为O(n2),平均情况下O(n)。

算法导论中还提到了最坏情况线性时间的选择。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 null ini n2