递归转非递归学习二:求斐波那契数列F(N)的值
来源:互联网 发布:千帆网络信息传媒 编辑:程序博客网 时间:2024/05/17 10:09
上《数据结构》的网络课程学习了递归转非递归的机械式转换的方法之后,
先练习写了N的阶乘方法转非递归(模拟栈)的代码,然后试着将斐波那契数列求F(N)的值的过程(模拟栈)转化为非递归:
#include <iostream>#include <stack>using namespace std;// (1). 设置工作栈中元素的结构体struct Datatype{ int n; // 当前输入数据n int fn; // FibonacciSequence(n)的返回值 int fn_1; // 局部变量FibonacciSequence(n-1)的值 int fn_2; // 局部变量FibonacciSequence(n-2)的值 int retAddr; // 模仿返回地址,调用第i个递归函数的标示符为i(i=1,2,3,...,t);t+1为栈底标示符,也是结束符};int FibonacciSequence(int N){ // (3). 增加非递归入口 // 初始化 Datatype currArea, areaTemp; // 当前栈中的元素,和一个临时元素 currArea.n = N; // 当前元素的n值 currArea.fn = 0; currArea.fn_1 = 0; currArea.fn_2 = 0; currArea.retAddr = 3; // 栈底"监视哨",作为整个循环的结束标志 int retResult = 0; // 存储最终结果的变量 // (1). 设置一个工作栈 stack<Datatype> s; s.push(currArea);// (2). 设置t+2个语句标号(t为递归函数内调用本身的次数,编号分别为0,1,...,t+1)// 由于例子中函数两次调用其本身,所以t=2label0: // 递归总入口 areaTemp = s.top(); // 获取栈顶元素的值,用来判断n的值 if (currArea.n <= 1) // 判断n的值小于等1,直接计算 { s.pop(); // 弹出栈顶元素,赋予新值之后再入栈 areaTemp.fn = currArea.n; // n=0或者1时,FibonacciSequence(n) = n; s.push(areaTemp); goto label3; // 转向递归调用总出口 } // 依次将FibonacciSequence(n-1)...FibonacciSequence(1)入栈 currArea.n--; currArea.fn = 0; currArea.fn_1 = 0; currArea.fn_2 = 0; currArea.retAddr = 1; // 第一处递归FibonacciSequence(n-1)的入口 s.push(currArea); goto label0;// (4). 替换第i(i=1...t)个递归规则label1: // 第一处递归函数的出口 areaTemp = s.top(); s.pop(); currArea = s.top(); s.pop(); currArea.fn_1 = areaTemp.fn; // 获得FibonacciSequence(n-1)的值,之后再入栈 s.push(currArea); currArea.n = currArea.n - 2; currArea.retAddr = 2; // 第二处递归FibonacciSequence(n-2) s.push(currArea); goto label0; // 进入递归总入口,为了计算第二处递归FibonacciSequence(n-2)的值label2: // 第二个递归调用的出口 areaTemp = s.top(); s.pop(); currArea = s.top(); s.pop(); currArea.fn_2 = areaTemp.fn; // 获得FibonacciSequence(n-2)的值 currArea.fn = currArea.fn_1 + currArea.fn_2; // 直接计算FibonacciSequence(n)的值 s.push(currArea); goto label3;label3: // 递归调用总出口,(6). 标号为t+1的语句格式 areaTemp = s.top(); switch(areaTemp.retAddr) { case 1: goto label1; break; case 2: goto label2; break; case 3: // 如果获得的是栈底元素,结束整个循环 s.pop(); // 退栈,清空栈 retResult = areaTemp.fn; break; default: cerr << "error label number in stack!" << endl; break; } return retResult;}// 尾递归转非递归,用循环结构求斐波那契数列int FibonacciSequence2(int n){ if (n <= 1) return n; long fib1 = 0, fib2 = 1; for (int i = 2; i <= n; i++) { fib2 = fib1 + fib2; // 得到新Fib2(n)的值 fib1 = fib2 - fib1; // 得到新Fib2(n-1)的值 } return fib2;}int main(){ int number; cin >> number; cout << FibonacciSequence(number) << endl; cout << FibonacciSequence2(number) << endl; return 0;}
- 递归转非递归学习二:求斐波那契数列F(N)的值
- 求斐波那契数列的第n个数(递归、非递归)
- 非递归方法求斐波那契数列的第n项
- 非递归求解斐波那契数列第n项的值
- 【C++】斐波那契数列前N项的和递归与非递归算法
- 非递归求斐波那契数列
- 求斐波那契数列的非递归解法;
- 斐波那契数列的递归及非递归
- Java学习之旅--斐波那契数列的递归和非递归实现
- 递归计算非波那契列的通项f(n)
- 数据结构之用递归和非递归方法计算斐波那契数列的第n项
- 【面试题】剑指offer09--递归法和非递归法斐波那契数列的第n个数
- 斐波那契数列的递归与非递归求解方法&递归的优缺点
- 实现斐波那契数列的递归、非递归及尾递归。
- 斐波那契数列的非递归实现
- 斐波那契数列的非递归实现 JAVA
- 斐波那契数列的非递归实现
- 斐波那契数列的非递归实现
- OSG Android版本编译
- JS禁用右键,禁用打印,防止另存为
- chenpi
- linux i2c驱动
- 高并发大数据量的数据库的设计与优化
- 递归转非递归学习二:求斐波那契数列F(N)的值
- 转储buffer cache
- mysql+keepalived 主主高可用集群配置
- Java 单例模式的七种写法
- MySQL同步 1032,1062异常
- ofbiz:设立sql语句在控制台的输出
- Android
- linux设备驱动之mmap函数
- 域、AD基础作用,概念介绍