小朋友学C语言(17):斐波那契数列的递归实现
2017-10-22 11:06
288 查看
什么是递归呢?先举个例子:
从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?”从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?’从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”
这个例子里,故事内嵌套着故事,构成了递归。
动手编写程序:
运行结果:
新知识点:
(1)
函数调用自身,就叫函数的递归调用。这个程序里,fibonacci()函数就调用了它本身。
但是不要以为return语句有两个fibonacci()函数,就误认为是2次调用自身。实际的调用次数是不固定的,要看n的值 。
咱们这里以n=5为例。
按照程序,有
fiboccina(5) = fiboccina(5 - 2) + fiboccina(5 - 1) = fiboccina(3) + fiboccina(4) ①
fiboccina(3)和fiboccina(4)同样会调用fiboccina()函数自身:
fiboccina(3) = fiboccina(3 - 2) + fiboccina(3 - 1) = fiboccina(1) + fiboccina(2) ②
fiboccina(4) = fiboccina(4 - 2) + fiboccina(4 - 1) = fiboccina(2) + fiboccina(3) ③
在②式里,fiboccina(1)和fiboccina(2)都不会调用自身,
因为n=1或n=2的时候,直接返回1。
所以fiboccina(3) = 1 + 1 = 2
在③中,fiboccina(2) = 1,fiboccina(3)会调用自身。
fiboccina(3) = fiboccina(1) + fiboccina(2) = 1 + 1 = 2
所以,fiboccina(4) = fiboccina(2) + fiboccina(3) = 1 + 2 = 3
将求得的fiboccina(3)和fiboccina(4)的值代入①,得
fiboccina(5) = fiboccina(3) + fiboccina(4) = 2 + 3 = 5,即为最终结果。
(2)
从(1)中的分析过程,可以看出n=5的时候,程序的执行顺序为
①–>②–>③–>④–>⑤–>⑥–>⑦–>⑧–>⑨
![](http://upload-images.jianshu.io/upload_images/6946981-eecdaa31c99aa15a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
(3)
从(1)和(2)的分析过程可以看出,n为1或2是递归的终止条件。无论原先输入的正自然数n的值是多少,最终都会递归减少到n=1或n=2的情况。
开头讲的那个例子,不是严格的递归,因为那个故事是讲不完的,没有终止条件。
作业:
(1)执行断点前,在fibonacci()加上printf(“n = %d\n”, n);
输入n = 1,用断点查看程序的执行过程。
输入n = 2,用断点查看程序的执行过程。
输入n = 3,用断点查看程序的执行过程。
输入n = 4,用断点查看程序的执行过程。
输入n = 5,用断点查看程序的执行过程。
输入n = 6,用断点查看程序的执行过程。
(2)默写这个程序
更多内容请关注微信公众号
从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?”从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?’从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”
这个例子里,故事内嵌套着故事,构成了递归。
动手编写程序:
#include <stdio.h> int fibonacci(int n) { if(1 == n || 2 == n) { return 1; } return fibonacci(n-2) + fibonacci(n - 1); } int main() { int m; printf("input m: "); scanf("%d", &m); int result = fibonacci(m); printf("fibonacci(%d) = %d\n", m, result); return 0; }
运行结果:
input m: 5 fibonacci(5) = 8
新知识点:
(1)
函数调用自身,就叫函数的递归调用。这个程序里,fibonacci()函数就调用了它本身。
但是不要以为return语句有两个fibonacci()函数,就误认为是2次调用自身。实际的调用次数是不固定的,要看n的值 。
咱们这里以n=5为例。
按照程序,有
fiboccina(5) = fiboccina(5 - 2) + fiboccina(5 - 1) = fiboccina(3) + fiboccina(4) ①
fiboccina(3)和fiboccina(4)同样会调用fiboccina()函数自身:
fiboccina(3) = fiboccina(3 - 2) + fiboccina(3 - 1) = fiboccina(1) + fiboccina(2) ②
fiboccina(4) = fiboccina(4 - 2) + fiboccina(4 - 1) = fiboccina(2) + fiboccina(3) ③
在②式里,fiboccina(1)和fiboccina(2)都不会调用自身,
因为n=1或n=2的时候,直接返回1。
所以fiboccina(3) = 1 + 1 = 2
在③中,fiboccina(2) = 1,fiboccina(3)会调用自身。
fiboccina(3) = fiboccina(1) + fiboccina(2) = 1 + 1 = 2
所以,fiboccina(4) = fiboccina(2) + fiboccina(3) = 1 + 2 = 3
将求得的fiboccina(3)和fiboccina(4)的值代入①,得
fiboccina(5) = fiboccina(3) + fiboccina(4) = 2 + 3 = 5,即为最终结果。
(2)
从(1)中的分析过程,可以看出n=5的时候,程序的执行顺序为
①–>②–>③–>④–>⑤–>⑥–>⑦–>⑧–>⑨
![](http://upload-images.jianshu.io/upload_images/6946981-eecdaa31c99aa15a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
(3)
从(1)和(2)的分析过程可以看出,n为1或2是递归的终止条件。无论原先输入的正自然数n的值是多少,最终都会递归减少到n=1或n=2的情况。
开头讲的那个例子,不是严格的递归,因为那个故事是讲不完的,没有终止条件。
作业:
(1)执行断点前,在fibonacci()加上printf(“n = %d\n”, n);
int fibonacci(int n) { printf(“n = %d\n”, n); if(1 == n || 2 == n) { return 1; } return fibonacci(n-2) + fibonacci(n - 1); }
输入n = 1,用断点查看程序的执行过程。
输入n = 2,用断点查看程序的执行过程。
输入n = 3,用断点查看程序的执行过程。
输入n = 4,用断点查看程序的执行过程。
输入n = 5,用断点查看程序的执行过程。
输入n = 6,用断点查看程序的执行过程。
(2)默写这个程序
更多内容请关注微信公众号
![](http://upload-images.jianshu.io/upload_images/6946981-7b6c65ad49a2c5be.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
相关文章推荐
- 小朋友学C语言(16):斐波那契数列的非递归实现
- C语言实现斐波那契数列(非递归)的实例讲解
- C语言不用递归(使用栈)实现斐波那契数列练习
- 用递归和非递归的方法输出斐波那契数列的第n个元素(C语言实现)
- C语言实现斐波那契数列的两种方法(递归和迭代)
- C语言递归方法实现斐波那契数列
- [算法]简单的背包问题递归解法,C语言实现
- 斐波那契数列 递归 尾递归 递推 C++实现
- 斐波那契数列递归及非递归实现及其应用
- 使用C语言递归与非递归实现字符串反转函数char *reverse(char *str)的方法
- 二叉树遍历的递归和非递归实现(C语言)
- 数据结构-C语言递归实现树的前中后序遍历
- 【数据结构与算法】汉诺塔算法——C语言递归实现
- C语言实现二叉树的递归遍历和非递归遍历
- 用递归实现斐波那契数列java实现
- C语言递归和非递归实现字符串反转
- 通过斐波那契数列分析实现函数时采用递归和循环的利弊
- Fibonacci (斐波那契数列)-循环,递归实现方式
- 兔子生娃问题---函数递归应用--c语言实现
- C语言实现任意长度多项式计算(非递归,不带括号)