1、递归程序1:Fibonacci数列可以用很直观的二叉递归程序来写,用C+语言的描述如下:longfib1(intn) if(n=2的时候我们分析可知:T(N)=T(N-1)+T(N-2)+2而fib(n)=fib(n-1)+fib(n-2),所以有T(N)=fib(n),归纳法证明可得:fib(N)4时,fib(N)=(3/2)N标准写法:显然这个O(3/2)N)是以指数增长的算法,基本上是最坏的情况。其实,这违反了递归的一个规则:合成效益法则。合成效益法则(Compoundinterestrule):在求解一个问题的同一实例的时候,切勿在不同的递归调用中做重复性的工作。所以在上面的代码中调用
2、fib(N-1)的时候实际上同时计算了fib(N-2)。这种小的重复计算在递归过程中就会产生巨大的运行时间。递归程序2:用一叉递归程序就可以得到近似线性的效率,用C+语言的描述如下:longfib(intn,longa,longb,intcount) if(count=n) returnb; returnfib(n,b,a+b,+count);longfib2(intn) returnfib(n,0,1,1);这种方法虽然是递归了,但是并不直观,而且效率上相比下面的迭代循环并没有优势。迭代解法:Fibonacci数列用迭代程序来写也很容易,用C+语言的描述如下:/也可以用数组将每次计算的f(n
3、)存储下来,用来下次计算用(空间换时间)longfib3(intn) longx=0,y=1; for(intj=1;jn;j+) y=x+y; x=y-x; returny;这时程序的效率显然为O(N),N=45的时候可以将它写成矩阵乘法形式:将右边连续的展开就得到:下面就是要用O(log(n)的算法计算:显然用二分法来求,结合一些面向对象的概念,C+代码如下:classMatrixpublic: longmatr22; Matrix(constMatrix&rhs); Matrix(longa,longb,longc,longd); Matrix&operator=(constMatrix
4、&); friendMatrixoperator*(constMatrix&lhs,constMatrix&rhs) Matrixret(0,0,0,0); 00=00*00+01*10; 01=00*01+01*11; 10=10*00+11*10; 11=10*01+11*11; returnret;Matrix:Matrix(longa,longb,longc,longd) this-matr00=a;matr01=b;matr10=c;matr11=d;Matrix(constMatrix&matr00=00;matr01=01;matr10=10;matr11=11;Matrix&
5、return*this;Matrixpower(constMatrix&m,intn) if(n=1) returnm; if(n%2=0) returnpower(m*m,n/2); returnpower(m*m,n/2)*m;longfib4(intn) Matrixmatrix0(1,1,1,0); matrix0=power(matrix0,n-1); 00;这时程序的效率为O(log(N)。公式解法:在O(1)的时间就能求得到F(n)了:注意:其中x表示取距离x最近的整数。用C+写的代码如下:longfib5(intn) doublez=sqrt; doublex=(1+z)/2;
6、 doubley=(1-z)/2; return(pow(x,n)-pow(y,n)/z+;这个与数学库实现开方和乘方本身效率有关的,我想应该还是在O(log(n)的效率。总结:上面给出了5中求解斐波那契数列的方法,用测试程序主函数如下:intmain() coutfib1(45)endl;fib2(45)fib3(45)fib4(45)coutfib5(45) return0;函数fib1会等待好久,其它的都能很快得出结果,并且相同为:。而后面两种只有在的时候会显示出优势。由于我的程序都没有涉及到高精度,所以要是求大数据的话,可以通过取模来获得结果的后4位来测试效率与正确性。另外斐波那契数列
7、在实际工作中应该用的很少,尤其是当数据n很大的时候(例如:),所以综合考虑基本普通的非递归O(n)方法就很好了,没有必要用矩阵乘法。1、N皇后问题算法设计ALGORITHMprocedurePLACE(k)/如果一个皇后能放在第k行的X(k)列,则返回true;否则返回false。X是一个全程数组,进入此过程时已置了k个值。/globalX(1:k);integeri,ki1whilei0do/对所有的行执行以下语句/X(k)X(k)+1/移到下一列/WhileX(k)nandnotPLACE(k)doX(k)X(k)十l;/如果第k个皇后的列X(k)不合理,就看下一列/ifX(k)n/找到一
8、个位置/thenifk=n/是一个完整的解吗/thenprint(X)/是,打印这个数组/elsekk+1;X(k)0;endif/扩展,搜索下一个皇后/elsekk1/回溯/endifendNQUEENSProgram:#includeintk=0,a20,j=1,flag,n,c=0;/k为解的个数,n为皇后的个数,flag标记有没有放置皇后voidlycQueen()/递归求解函数inti,h;/i为行号,h为列号for(h=1;h=n;h+)aj=h;for(i=1;ij;i+)/将第j个皇后的位置依次跟前面j-1个皇后比较if(ai=aj|abs(aj-ai)=abs(j-i)fla
9、g=0;break;/两个皇后在同一行或者同一对角线上,冲突elseflag=1;/没冲突,放置一个皇后/forif(flag=0&aj!=n)continue;/没试探完,继续试探if(flag=1&j=n)/放置完n个皇后,得到一个解k=k+1;c=1;/解的个数加1i+)printf(%d,ai);/输出第i个皇后放置的行号nif(aj=n)flag=0;/ifj!=n)j+;lycQueen();/递归调用aj=n)j-;/回溯,退回去重新试探/lycQueenvoidmain()inti;请输入皇后的个数:scanf(,&n);/输入皇后的个数nj=1;i+)aj=i;j=j+1;/调用lycQueen函数if(c=1)j=1;解的个数为%d个n,k);/main
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1