求一组随机数中的最大最小值最少比较次数
1. 求一组随机数中的最大值和最小值最少比较次数为3n/2-2取上整次,即大于等于3n/2-2的最小整数次。
当n为偶数时,为3n/2-2
当n为奇数时,为3n/2-3/2
2. 算法如下。
第一步,将这组数据两两比较,将小数置于数组前半部分,大数置于数组后半部分。如果n为偶数,此次比较次数为n/2;如果n为奇数,此次比较次数为(n-1)/2,中间的那个数不做比较。
第二步,在数组的前半部分进行比较找到最小的数;在数组的后半部分比较找到最大的数。如果n为偶数,总共比较次数为(n/2-1)×2次;如果n为奇数,比较次数为((n-1)/2-1)×2次。
第三步,如果n为奇数,将数组中间数a[length/2]与min和max比较,找到最小值和最大值,比较次数为2;如果n为偶数,最大值和最小值已经找到,此次什么也不做。
综上所述,n为偶数,总共比较次数为:n/2+(n/2-1)×2=3n/2-2
n为奇数,总共比较次数为:(n-1)/2+((n-1)/2-1)×2+2=3(n-1)/2=3n/2-3/2
代码如下:
View Code
1 #include <iostream> 2 #include <cassert> 3 4 using namespace std; 5 6 void MinMaxSelect(int* a,const int lengh,int &max,int &min) 7 { 8 assert(a); 9 min=INT_MAX; 10 max=INT_MIN; 11 int i=0; 12 int j=lengh-1; 13 while(i< j) 14 { 15 if (a[i]>a[j]) 16 { 17 swap(a[i],a[j]); 18 } 19 i++; 20 j--; 21 } 22 for (int i=0;i<(lengh+1)/2;i++) 23 { 24 if (a[i]<min) 25 { 26 min=a[i]; 27 } 28 } 29 for (int i=(lengh+1)/2;i<lengh;i++) 30 { 31 if (a[i]>max) 32 { 33 max=a[i]; 34 } 35 } 36 if (lengh%2!=0) 37 { 38 int middle=lengh/2; 39 if (a[middle]<min) 40 { 41 min=a[middle]; 42 } 43 if (a[middle]>max) 44 { 45 max=a[middle]; 46 } 47 } 48 } 49 50 int main() 51 { 52 enum {EvenLength=10,OddLength}; 53 int a[EvenLength]={2,4,5,1,3,9,6,8,0,10}; 54 int max; 55 int min; 56 MinMaxSelect(a,EvenLength,max,min); 57 cout<<"max= "<<max<<"\tmin= "<<min<<endl; 58 59 int b[OddLength]={2,0,5,11,3,9,6,8,1,10,11}; 60 MinMaxSelect(b,OddLength,max,min); 61 cout<<"max= "<<max<<"\tmin= "<<min<<endl; 62 return 0; 63 }