C++程序性能2 //C++程序性能2 //ProgramPerformance2.h //查找最大和最小值函数 template<class T> bool MinMax(T a[],int n,int& Min,int& Max) { //寻找a[0:n-1]中的最小元素和最大元素 //如果数组中的元素数目小于1,则返回false if(n<1) return false; Min=Max=0;//初始化 for(int i=1;i<n;i++) { if(a[Min]>a[i]) Min=i; if(a[Max]<a[i]) Max=i; } return true; } //另一个查找最大和最小值函数 template<class T> bool MinMax_other(T a[],int n,int& Min,int& Max) { //寻找a[0:n-1]中的最小元素和最大元素 //如果数组中的元素数目小于1,则返回false if(n<1) return false; Min=Max=0;//初始化 for(int i=1;i<n;i++) { if(a[Min]>a[i]) Min=i; else if(a[Max]<a[i]) Max=i; } return true; } /* 之所以要确定程序的操作计数和执行步数有两个重要的原因: 1)为了比较两个完成同一功能的程序的时间复杂性; 2)为了预测随着实例特征的变化,程序运行时间的变化量。 ----- 利用新符号可以写出关于程序时间和空间复杂性的具体公式(尽管不够精确)。 这种符号被称为渐进符号(asymptotic notation), 它可以描述大型实例特征下时间或空间复杂性的具体表现。 在下面的讨论中f (n) 表示一个程序的时 间或空间复杂性,它是实例特征n的函数。 由于一个程序的时间和空间需求是一个非负值, 所以可以假定对于n的所有取值,函数f的值非负。 由于n表示一个实例特征,所以可以进一步假定n≥0。 即将讨论的渐进符号允许我们对于足够大的n值, 给出f的上限值和/或下限值 ----- 大写O 符号给出了函数f的一个上限。 定义[大写O符号] f (n)=O (g (n)) 当且仅当存在正的常数c 和n0,使得对于所有的n≥n0 , 有 f (n) ≤c g(n)。 //上限函数g(n) ---- 常用的渐进函数 1 常数 logn 对数 n 线性 nlogn n个logn n^2 平方 n^3 立方 2^n 指数 n! 阶乘 ---- f(n)=3n+2 f(n)=O(n) f(n)=10n^2+4n+2 f(n)=O(n^2) f(n)=6*2^n+n^2 f(n)=O(2^n) 因为有n^2<=2^n f(n)=9;f(n)=2033 f(n)=O(1) ---- 定义: 如果f(n)=am*n^m+...+a1*n+a0且am>0,则f(n)=O(n^m) ---- Ω符号与大O 符号类似,它用来估算函数f 的下限值 ---- Θ符号适用于同一个函数g 既可以作为f 的上限也可以作为f 的下限的情形。 ---- 定义[小写o] f (n)=o (g (n) )当且仅当f (n) = O (g (n) )且f (n)≠W (g (n) ) ---- 3n+2=o(n^2) 10n^2+4n+2=o(n^3); ---- */ //折半搜索函数 template<class T> int BinarySearch(T a[],const T& x,int n) { //在a[0]<=a[1]<=...<=a[n-1]中搜索x //如果找到,则返回所在位置,否则返回-1 int left=0;int right=n-1; while(left<=right) { int middle=(left+right)/2; if(x==a[middle]) return middle; if(x>a[middle]) left=middle+1; else right=middle-1; } return -1;//未找到x } /* 性能测量(performance measurement)主要关注于得到一个程序实际需要的空间和时间。 ---- 基于以下原因,我们不能精确地测量一个程序运行时所需要的时间和空间: 1)指令空间和数据空间的大小是由编译器在编译时确定的,所以不必测量这些数据。 2)采用前几节介绍的方法,可以很准确地估算递归栈空间和变量动态分配所需要的空间。 ---- 选择实例的大小 可以根据以下两个因素来确定使用哪些n 值:程序执行的时间及执行的次数 在实践过程中,通常需要3个以上的n 值,其原因如下: 1) 渐进分析仅给出了对于足够大的n 值时程序的复杂性。对于小的n 值,程序的运行时间 可能并不满足渐进曲线。为了确定渐进曲线以外的点,需要使用多个n 值。 2) 即使在满足渐进曲线的区间内,程序实际运行时间也可能不满足预定的渐进曲线,原因 是在进行渐进分析时,忽略了许多低层次的时间需求。 ---- 设计测试数据 对于许多程序,可以手工或用计算机来产生能导致最好和最坏复杂性的测试数据。 然而,对于平均的复杂性,通常很难设计相应的数据 当不能给出能产生预期的复杂性的测试数据时,可以根据一些随机产生的测试数据所测量 出的最小(最大,平均)时间来估计程序的最坏(最好,平均)复杂性 ---- 进行实验 在确定了实例的大小并给出了测试数据以后,就可以编写程序来测量所期望的运行时间了 ---- */ // Win32Console.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "baseCplusplus1.h"; #include "baseClassRelInfo2.h"; #include "TestProgram.h" #include "ProgramPerformance.h" #include "ProgramPerformance2.h"; void baseCplusplusOp(); //C++函数模板递归一二维数组动态分配存储空间实例1 void baseClassRelInfo2(); //C++类的相关基础2 void baseClassRelInfo2_1(); //C++类的相关基础2 //操作符重载 void ComputeRoots(); //计算根公式 void findMax(); //寻找最大值 void ProgramPerformance(); //程序性能1 void ProgramPerformance2(); //程序性能2 int _tmain(int argc, _TCHAR* argv[]) { baseCplusplusOp(); baseClassRelInfo2(); std::cout<<"/操作符重载"<<std::endl; baseClassRelInfo2_1(); std::cout<<"计算根公式"<<std::endl; ComputeRoots(); std::cout<<"寻找最大值"<<std::endl; findMax(); std::cout<<"程序性能"<<std::endl; ProgramPerformance(); std::cout<<"程序性能2"<<std::endl; ProgramPerformance2(); //暂停操作 char str; std::cin>>str; //程序结束 return 0; } //程序性能2 void ProgramPerformance2() { int a[11]={1,5,2,6,9,11,18,20,25,7,30}; int n=11; int x=7; for(int i=0;i<n;i++) std::cout<<a[i]<<" "; std::cout<<std::endl; BubbleSort_intimestop(a,n); //排序 std::cout<<"折半搜索"<<std::endl; int pos=BinarySearch(a,x,n); std::cout<<x<<" pos="<<pos<<std::endl; for(int i=0;i<n;i++) std::cout<<a[i]<<" "; std::cout<<std::endl; }