C++递归的学习理解!

vloso 2018-06-19 11:31:07
#include <iostream>
#include <windows.h>
using namespace std;

int fib(int n);

int main()
{
int a;
//while(cin>>a)
//{
cout<<"the result: "<<fib(10)<<endl;
// }
return 0;
}

int fib(int n)
{
cout<<n<<endl;
if(n==1||n==2)
return 1;


else
return fib( n-1)+fib( n-2);


}




递归的概念是理解的,就是不断调用自身函数遇到n==1或 n==2就向上返回,

如上代码第一层递归应该是 fib(9-1)+fib(9-2) + fib(8-1)+fib(8-2)

疑问1:每一层函数 n 的变量 它最终结果是 等于1或2 进行结束返回上一层,从而这一层的函数结果最终输出=1 ?

疑问2:它递归出来的结果 怎么样相加 然后等于最终结果的,这个真的看不懂!




看了一天百度了,各种类型都看了还是不懂,求大神解惑一下的,
...全文
771 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
northwesternwind 2018-06-25
  • 打赏
  • 举报
回复
兄弟,从你的问题可以看出来,你还是陷入了错误的思路不能自拔。建议你还是用赵老师的办法,比如输入一个3,单步执行,一步一步观察最终结果咋来的。否则感觉讨论不在一个频道上
引用 7 楼 vloso 的回复:
[quote=引用 1 楼 northwesternwind 的回复:]
你的思路根本就不对。底归处理为了理解,可以试着一层层运行,但是这样太麻烦。只要看懂公式就可以了:

return fib( n-1)+fib( n-2);

这就是f函数的递推公式: fib(n)=fib(n-1)+fib(n-2), 至于fib(n-1)和fib(n-2), 它们又是利用递推计算出来的。
当n=1或者n=2的时候,fib(n)的结果直接等于1.
然后fib(3), fib(4)等等这些利用递归就可以计算出来了。

比如fib(3)= fib(2)+fib(1) = 1+ 1 = 2

引用
疑问2:它递归出来的结果 怎么样相加 然后等于最终结果的,这个真的看不懂!

函数返回值就是 return 的两个相加的结果啊?


哥们我再次翻阅了百度的二叉树分析图,我开始的确理解错误,恕我再问一下,从公式上我们是如何看出结果的,这个实在是困惑啊,

今天我干了一天,得出的结果是:递归就是它在过程里分裂出多少个符合判断:例如(if(n==1));假设有99个符合都等于1,那么相加返回就是99;那么请教一个问题,我随便输入一个简单的数字

我们怎么可以推算出他里面包含多少个符合要求的结果!
[/quote]
赵4老师 2018-06-20
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察
书香门第 2018-06-20
  • 打赏
  • 举报
回复
引用 6 楼 vloso 的回复:
[quote=引用 3 楼 weixin_42325834 的回复:] 我也试着解释一下。fib数列的定义是:1, 1, 2, 3, 5, 8, 。。。 也就是说每个元素是前面相邻两个元素的和,而第一个和第二个元素是不符合这个定义的,因为他们前面没有两个相邻的元素,所以这两个元素直接定义为1和1 回到你的程序,n表示fib数列中的第n个元素,所以按照定义f(n) = f(n-1) + f(n-2), 而n=1和n=2的话就返回1。 比如,我们现在求第10个元素,看你的程序怎么运行的。f(10) = f(9) + f(8),首先你的程序会进一步调用f(n=9),这个函数又会去求f(9) = f(8) + f(7), 然后又去求f(8) = f(7) + f(6), 。。。这样一直到f(3) = f(2) + f(1), 而f(2)则会返回1,f(1)也会返回1,不会进一步调用了,所以f(3) = 1 + 1,返回2, 。。。这样就可以一层层返回。 这也就是递归调用的精髓所在,要求第10个,现要求第9个和第8个。问题本质一样,但是参数变小了。而要求第8个先要求第7个和第6个,进一步变小,直到小到一定程度,也就是第1个和第2个,不再依赖其它更小的元素而返回,这样前面那些元素的依赖条件满足了就可以得到答案了。
兄弟还在吗?通过翻阅资料我理解的是这样,,我举个例子:假设 当n==0的时候这个函数就结束并返回 1 的结果!递归的原理就是他不断去分裂到底有多少个函数符合 if(n==0)结果返回 1 ,,比喻这个递归出来是100个符合要求的 我们相加它就是 100的结果 请问是不是这样的理解[/quote] 不完全对。不断分裂是对的,但是只有最后一次调用时n是1或者是2直接返回结果1,所以它是最后一次调用。其它的调用都是依赖某个更小的n的返回结果。你可以看8楼分解的结果,注意每一个f就是一次调用,所以过程就是每个n不断去依赖并调用更小的n的结果,直到最后到了n等于1或者2时不再依赖而是返回1,再一步一步往上退。你仔细体会一下依赖的意思,然后可以单步运行一下程序,在纸上画一画调用的过程,应该会比较清楚了。
书香门第 2018-06-19
  • 打赏
  • 举报
回复
我也试着解释一下。fib数列的定义是:1, 1, 2, 3, 5, 8, 。。。 也就是说每个元素是前面相邻两个元素的和,而第一个和第二个元素是不符合这个定义的,因为他们前面没有两个相邻的元素,所以这两个元素直接定义为1和1 回到你的程序,n表示fib数列中的第n个元素,所以按照定义f(n) = f(n-1) + f(n-2), 而n=1和n=2的话就返回1。 比如,我们现在求第10个元素,看你的程序怎么运行的。f(10) = f(9) + f(8),首先你的程序会进一步调用f(n=9),这个函数又会去求f(9) = f(8) + f(7), 然后又去求f(8) = f(7) + f(6), 。。。这样一直到f(3) = f(2) + f(1), 而f(2)则会返回1,f(1)也会返回1,不会进一步调用了,所以f(3) = 1 + 1,返回2, 。。。这样就可以一层层返回。 这也就是递归调用的精髓所在,要求第10个,现要求第9个和第8个。问题本质一样,但是参数变小了。而要求第8个先要求第7个和第6个,进一步变小,直到小到一定程度,也就是第1个和第2个,不再依赖其它更小的元素而返回,这样前面那些元素的依赖条件满足了就可以得到答案了。
vloso 2018-06-19
  • 打赏
  • 举报
回复
引用 1 楼 northwesternwind 的回复:
你的思路根本就不对。底归处理为了理解,可以试着一层层运行,但是这样太麻烦。只要看懂公式就可以了:

return fib( n-1)+fib( n-2);
这就是f函数的递推公式: fib(n)=fib(n-1)+fib(n-2), 至于fib(n-1)和fib(n-2), 它们又是利用递推计算出来的。 当n=1或者n=2的时候,fib(n)的结果直接等于1. 然后fib(3), fib(4)等等这些利用递归就可以计算出来了。 比如fib(3)= fib(2)+fib(1) = 1+ 1 = 2
引用
疑问2:它递归出来的结果 怎么样相加 然后等于最终结果的,这个真的看不懂!
函数返回值就是 return 的两个相加的结果啊?
你好,,我所产生的疑问是每一层函数都要等于1或2才会退出,如果是这样是不是 每一层函数 1+1+1+1这样相加下去??
northwesternwind 2018-06-19
  • 打赏
  • 举报
回复
你的思路根本就不对。底归处理为了理解,可以试着一层层运行,但是这样太麻烦。只要看懂公式就可以了:

return fib( n-1)+fib( n-2);
这就是f函数的递推公式: fib(n)=fib(n-1)+fib(n-2), 至于fib(n-1)和fib(n-2), 它们又是利用递推计算出来的。 当n=1或者n=2的时候,fib(n)的结果直接等于1. 然后fib(3), fib(4)等等这些利用递归就可以计算出来了。 比如fib(3)= fib(2)+fib(1) = 1+ 1 = 2
引用
疑问2:它递归出来的结果 怎么样相加 然后等于最终结果的,这个真的看不懂!
函数返回值就是 return 的两个相加的结果啊?
ooolinux 2018-06-19
  • 打赏
  • 举报
回复
一个关于递归函数的很清晰的例子 http://blog.163.com/tab_98/blog/static/119240972016612101644600/
licjd 2018-06-19
  • 打赏
  • 举报
回复
就拿你的程序为例: 开始: 结束: f(10) = f(10 - 1) + f(10- 2) = f(9) + f(8); f(10) = 34 + 21 = 55 f(9) = f(9 - 1) + f(9 - 2) = f(8) + f(7); f(9) = 21 + 13 = 34 f(8) = f(8 - 1) + f(8- 2) = f(7) + f(6); f(8) = 13 + 8 = 21 f(7) = f(7 - 1) + f(7 - 2) = f(6) + f(5); f(7) = 8 + 5 = 13 f(6) = f(6 - 1) + f(6- 2) = f(5) + f(4); f(6) = 5 + 3 = 8 f(5) = f(5 - 1) + f(5 - 2) = f(4) + f(3); f(5) = 3 + 2 = 5 f(4) = f(4 - 1) + f(4- 2) = f(3) + f(2); f(4) = 2 + 1 = 3 f(3) = f(3 - 1) + f(3 - 2) = f(2) + f(1); f(3) = 1 + 1 = 2 f(2) = f(1) = 1; 对于递归,建议楼主多用笔运算的看看,慢慢的就会理解(本人经验)。
vloso 2018-06-19
  • 打赏
  • 举报
回复
引用 1 楼 northwesternwind 的回复:
你的思路根本就不对。底归处理为了理解,可以试着一层层运行,但是这样太麻烦。只要看懂公式就可以了:

return fib( n-1)+fib( n-2);
这就是f函数的递推公式: fib(n)=fib(n-1)+fib(n-2), 至于fib(n-1)和fib(n-2), 它们又是利用递推计算出来的。 当n=1或者n=2的时候,fib(n)的结果直接等于1. 然后fib(3), fib(4)等等这些利用递归就可以计算出来了。 比如fib(3)= fib(2)+fib(1) = 1+ 1 = 2
引用
疑问2:它递归出来的结果 怎么样相加 然后等于最终结果的,这个真的看不懂!
函数返回值就是 return 的两个相加的结果啊?
哥们我再次翻阅了百度的二叉树分析图,我开始的确理解错误,恕我再问一下,从公式上我们是如何看出结果的,这个实在是困惑啊, 今天我干了一天,得出的结果是:递归就是它在过程里分裂出多少个符合判断:例如(if(n==1));假设有99个符合都等于1,那么相加返回就是99;那么请教一个问题,我随便输入一个简单的数字 我们怎么可以推算出他里面包含多少个符合要求的结果!
vloso 2018-06-19
  • 打赏
  • 举报
回复
引用 3 楼 weixin_42325834 的回复:
我也试着解释一下。fib数列的定义是:1, 1, 2, 3, 5, 8, 。。。 也就是说每个元素是前面相邻两个元素的和,而第一个和第二个元素是不符合这个定义的,因为他们前面没有两个相邻的元素,所以这两个元素直接定义为1和1 回到你的程序,n表示fib数列中的第n个元素,所以按照定义f(n) = f(n-1) + f(n-2), 而n=1和n=2的话就返回1。 比如,我们现在求第10个元素,看你的程序怎么运行的。f(10) = f(9) + f(8),首先你的程序会进一步调用f(n=9),这个函数又会去求f(9) = f(8) + f(7), 然后又去求f(8) = f(7) + f(6), 。。。这样一直到f(3) = f(2) + f(1), 而f(2)则会返回1,f(1)也会返回1,不会进一步调用了,所以f(3) = 1 + 1,返回2, 。。。这样就可以一层层返回。 这也就是递归调用的精髓所在,要求第10个,现要求第9个和第8个。问题本质一样,但是参数变小了。而要求第8个先要求第7个和第6个,进一步变小,直到小到一定程度,也就是第1个和第2个,不再依赖其它更小的元素而返回,这样前面那些元素的依赖条件满足了就可以得到答案了。
兄弟还在吗?通过翻阅资料我理解的是这样,,我举个例子:假设 当n==0的时候这个函数就结束并返回 1 的结果!递归的原理就是他不断去分裂到底有多少个函数符合 if(n==0)结果返回 1 ,,比喻这个递归出来是100个符合要求的 我们相加它就是 100的结果 请问是不是这样的理解
vloso 2018-06-19
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出
赵四老师,,问个问题,所谓递归是不是一直调用循环到有多少个符合要求判断的:例: if(n==0)return 1; 然后再相加/减/乘/除,, 比喻调用函数过程里演示只有10个(全部)函数符合 n==0,那么就是10个函数相加 1+1+1....=10是不是这样概念啦? 还有个疑问:我如何得知这个数值可以递归出多少个符合要求的数值啦?
赵4老师 2018-06-19
  • 打赏
  • 举报
回复
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

64,680

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧