在c++中尾递归,普通递归,循环的效率对比
来源:互联网 发布:计算机中数据存储方式 编辑:程序博客网 时间:2024/05/22 13:45
在前面的学习,我们知道普通递归和尾递归的区别,而且在有些语言里是极力提倡尾递归的,如erlang,因为编译器会对其进行优化,不会因为递归次数的增加给函数栈带来巨大的开销。但是c++语言中,g++会对其进行优化吗?现在通过实例分析,看看结论会是什么?
斐波那契数列: 1,1,2,3,5,......
通过c++编程来求斐波那契数列的第N项的值。试用两种方法,一种是普通递归,另一种是尾递归。
然后统计他们计算第N项的值所花费的时间,来比较两者间的效率。
#include <iostream>#include <ctime>using namespace std;// Normal recusion for fibonacciunsigned int fib_normal_rec(unsigned int n){ if (n <= 2) return 1; else return fib_normal_rec(n-1) + fib_normal_rec(n-2);}// Rail recusion for fibonacciunsigned int fib_rail_rec(unsigned int n, unsigned int first, unsigned int second){ if (n == 1) return first; if (n == 2) return second; return fib_rail_rec(n-1, second, second+first);}unsigned int fib_rail_rec(unsigned int n){ return fib_rail_rec(n, 1, 1);}// No recusionunsigned int fib_no_rec(unsigned int n){ if (n <= 2) return 1; unsigned int x=1, y=1, y_tmp=0; for (unsigned int i=0; i<n-2; i++) { y_tmp = y; y = x+y; x = y_tmp; } return y;}int main(){ // fib NUM unsigned int fib_num = 10000000000; unsigned int t1 = time(NULL); //cout <<"Normal fib:" << fib_num << " --> " << fib_normal_rec(fib_num) << endl; unsigned int t2 = time(NULL); cout << "Normal fib time cost:" << t2-t1 << endl; cout << "----------------------------------------------------------" << endl; //cout <<"Rail fib:" << fib_num << " --> " << fib_rail_rec(fib_num) << endl; unsigned int t3 = time(NULL); cout << "Rail fib time cost:" << t3-t2 << endl; cout << "---------------------------------------------------------" << endl; cout <<"No recusion fib:" << fib_num << " --> " << fib_no_rec(fib_num) << endl; unsigned int t4 = time(NULL); cout << "No recusion fib time cost:" << t4-t3 << endl; return 0;}
经过反复加注释编译,设置fib_num的大小,最后得出如下测试结果:
非尾递归:当fib_num=45,花费8秒左右得到正确值。
当fib_num设置成50时,运行时间有点长,就没继续等下去了。
尾递归:当fib_num=100000时,0秒得到正确值。
当fib_num=1000000时,0秒得到段错误。
循环: 当fib_num=100000000 时,0秒得到正确值。
当fib_num=1000000000 时,4秒得到正确值。
当fib_num=10000000000 时,编译会出警告:
recursion.cpp: In function 'int main()':
recursion.cpp:45: warning: large integer implicitly truncated to unsigned type
个人得出的结论:
尾递归和循环的执行效率都非常高。但是尾递归的递归层数大到一定程度会出现段错误。
尾递归的函数栈开销比普通递归要小的多,执行效率也要大很多。但是并不是说尾递归就没有函数栈开销。
正因为尾递归具有函数栈开销,其计算极限要比非递归(循环)小很多。
总之:如果只考虑计算能力,实现一个功能,能不用递归就别用递归,能用尾递归就别用非尾递归。
0 0
- 在c++中尾递归,普通递归,循环的效率对比
- 迭代 递归 普通循环的区别
- 递归与循环的效率问题
- 递归和循环的效率问题
- 递归的效率问题及递归与循环比较
- 递归的效率问题及递归与循环比较
- ArrayList与LinkedList的普通for循环遍历效率对比
- 递归,尾递归,循环
- 递归和循环效率比较
- 递归与尾递归的循环实现
- for循环和递归算法的运行效率比较(c语言)
- 计算fibonacci数列 - 递归和迭代的效率对比
- C语言之三种循环结构与递归函数的对比
- 优化递归的效率
- mysql中普通索引和唯一索引的效率对比
- Javascript递归与各种循环执行效率的比较
- 快排的递归和非递归实现和效率对比
- C:单链表的循环和递归实现
- xshell window远程到linux服务器,文件传输
- 数据库编码修改
- 谷歌J2ObjC:打破Android应用与iOS应用之间的语言障碍
- 科摩多数据备份工具下载
- Windows程序内部运行机制学习
- 在c++中尾递归,普通递归,循环的效率对比
- Android——谷歌官方下拉刷新控件SwipeRefreshLayout
- Mapper XML文件
- NSArray / NSDictionary 的基本介绍和使用
- 数据挖掘与机器学习关系与区别
- 使用JS为按钮添加快捷键
- Python系列之 - python数据类型(二)
- 使用jquery现实图片切换效果
- java调用webservice并解析json字段