最小最大数
#include<iostream> #include<vector> #include<ctime> #define N 1000 using namespace std; int count1,count2,count3; //算法1,2来自编程珠玑 void minmax(vector<int> a){ int min=a[0]; int max=a[0]; int n=a.size(); for(int i=1;i<n;i++){ if(a[i]<min){ min = a[i]; } if(a[i]>max){ max=a[i]; } count1 += 2; } cout<<"min,max="<<min<<","<<max<<endl; } void minmax2(vector<int> a){ int min=a[0]; int max=a[0]; int n=a.size(); for(int i=1;i<n;i++){ if(a[i]<min){ min = a[i]; ++count2; } else{ if(a[i]>max){ max=a[i]; } count2 += 2; } } cout<<"min,max="<<min<<","<<max<<endl; } void minmax3(vector<int> a){//来自算法导论 int n = a.size(); int min=a[0]; int max; int k; if(n%2!=0){ max = a[0]; k=1; } else{ max = a[1]; k=2; } for(;k<n;k += 2){ if(a[k]<a[k+1]){ if(a[k]<min){ min = a[k]; } if(a[k+1]>max){ max = a[k+1]; } } else{ if(a[k+1]<min){ min = a[k+1]; } if(a[k]>max){ max = a[k]; } } count3 += 3; } cout<<"min,max="<<min<<","<<max<<endl; } int main(){ vector<int> a; for(int i=0;i<N;i++){ a.push_back(i); } for(int i=0;i<N;i++){ swap(a[i],a[rand()%(N-i)+i]); } //clock_t st,fi,st2,fi2,st3,fi3; //st = clock(); minmax(a); //fi = clock(); cout<<"minmax比较次数 :"<<count1<<endl; cout<<endl; //st2 = clock(); minmax2(a); //fi2 = clock(); cout<<"minmax2比较次数"<<count2<<endl; cout<<endl; //st3 = clock(); minmax3(a); //fi3 = clock(); cout<<"minmax3比较次数"<<count3<<endl; return 0; }
算法1,2来自<<编程珠玑续>>第一章第一题,2是对1的优化,因为如果a[i]<min,那么a[i]不可能大于max.但这样做优化幅度并不大,假设a中元素均匀散布,Knuth证明a[i]<min成立的次数为HN-1,其中HN=1+1/2+1/3+..+1/N,即为第N个调和数.对于N=1000,其期望值为6.485.
算法3来自<<算法导论>>,思路如下:
1. Pick 2 elements(a, b), compare them. (say a > b) 2. Update min by comparing (min, b) 3. Update max by comparing (max, a)
比较次数为3N/2证明如下:
This way you would do 3 comparisons for 2 elements, amounting to 3N/2 total comparisons for N elements.
程序运行结果:(N=1000)
虽然比较次数有区别,但当N较大(N=1000000)时,三个算法的实际运行时间并无太大差别.当N更大(N=100000000)时,可以明显看出算法3最慢,算法2最快,算法1次之.
N=1000000 N=100000000