在一个由n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素。
输入:一个包含n个(互异的)数的集合A和一个整数i,1<=i<=n。
输出:A中的一个元素x,且A中恰好有i-1个其他元素小于它。
本来可以在O(n*lgn)内解决此问题,即排序后输出即可。本节使其在线性时间O(n)内完成。
1、 本算法的期望运行时间为T(n)=O(n),最坏运行时间为O(n^2)。
1 #include<stdio.h> 2 int RANDOMZED_SELECT(int A[],int p,int r,int i){ 3 int q,k; 4 if(p==r) 5 return A[p]; 6 q=RANDOMIZED_PARTITION(A,p,r); 7 k=q-p+1; 8 if(i==k) 9 return A[q]; 10 else if(i<k) 11 return RANDOMZED_SELECT(A,p,q-1,i); 12 else 13 return RANDOMZED_SELECT(A,q+1,r,i-k); 14 } 15 16 int RANDOMIZED_PARTITION(int A[],int p, int r){ 17 int x,i; 18 i=rand()%(r-p)+p; 19 x=A[i]; 20 A[i]=A[r]; 21 A[r]=x; 22 return PARTITION(A,p,r); 23 } 24 int PARTITION(int A[],int p,int r){ 25 int i,j,x,t; 26 i=p-1; 27 x=A[r]; 28 for(j=p;j<r;j++) 29 if(A[j]<=x){ 30 i++; 31 t=A[i]; 32 A[i]=A[j]; 33 A[j]=t; 34 } 35 t=A[i+1]; 36 A[i+1]=A[r]; 37 A[r]=t; 38 return i+1; 39 } 40 void main(){ 41 int A[9]={0,1,4,7,9,8,6,3,2}; 42 int x=0; 43 int i=0; 44 printf("数组A为:"); 45 for(i=0;i<9;i++) 46 printf("%d ",A[i]); 47 x=RANDOMZED_SELECT(A,0,9,5); 48 printf(" 从A[0]到A[9],第5大的元素是:"); 49 printf("%d ",x); 50 }
2、算法的最坏运行时间为O(n)
采用特殊的方式将数组每次按比例划分。此思想可运用到快排上,算法略了。