斐波那契数例题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

斐波那契数例题

  • 1.斐波那契数(递归实现和非递归实现)
    • 1.1递归的实现
    • 1.2非递归的实现
    • 1.3斐波那契数的非递归的实现优于递归实现的原因
  • 2.经典问题之《青蛙跳台阶》
  • 3.经典问题之《汉诺塔问题》
  • 总结

1.斐波那契数(递归实现和非递归实现)

1.1递归的实现

题目描述:

计算斐波那契数递归实现求第n个斐波那契数
例如:
输入:5 输出:5
输入:10, 输出:55
输入:2, 输出:1

解题思路:斐波那契数是前两项加起来等于后一项:1,1,2,3,5,8,13…,所以我们可以以n<=2为限制条件,当n=1或2时,返回1,然后到n=3项时就是n=1项和n=2项之和,然后依次往后推,即Fib(n)就是Fib(n-1)和Fib(n-2)之和

Fib(n)
Fib(n-1) + Fib(n-2)
Fib(n-2)+Fib(n-3) , Fib(n-3)+Fib(n-4)

一直递推下去,直至到Fib(1)和Fib(2)返回值为1,然后回归,得到第n个斐波那契数

代码实现:
斐波那契数例题_第1张图片
斐波那契数例题_第2张图片

1.2非递归的实现

题目描述:

计算斐波那契数递归实现求第n个斐波那契数
例如:
输入:5 输出:5
输入:10, 输出:55
输入:2, 输出:1

解题思路:也可以参考上面递归实现的思路,我们可以用三个变量相互替换来解决,n1为第一项,n2为第二项,tmp为第三项,运用while()循环,每一次循环n就减1,直到n=2,最后输出tmp。

n=5
n1=1,n2=1 ,tmp=n1+n2=2
n1=n2=1,n2=tmp=2,tmp=n1+n2=3

依次类推直到n为2停下,即可得第n个斐波那契数

代码实现
斐波那契数例题_第3张图片

1.3斐波那契数的非递归的实现优于递归实现的原因

①.函数递归的原则是“大事化小”,对于很多问题的求解上是很遍历,而且非常迅速。但是他也是有缺点的,世界上没有完美的“事物”,函数递归也不例外。因为每一次函数递归(函数调用)都会在函数栈帧上开辟一块空间,所谓的压栈。这样会大大降低我们代码的执行效率

②.这题用递归法实现的斐波那契数正对应了其缺点因为它的递推时会有很多分支,一个分支下面又有很多分支,每一个小分支都是函数的调用,然而还有回归,函数栈帧需要销毁,这会大大降低代码的执行效率,如果n=50,则代码执行时间都要1个多小时,所以用递归法实现的斐波那系数其实是不实用的。

③.而用非递归的方法实现,可以大大提高代码的运行效率。只是每一次循环,n1,n2,tmp会被赋值,代码执行次数大大减少,所以斐波那契数的非递归的实现优于递归实现的。

2.经典问题之《青蛙跳台阶》

题目描述:

青蛙一次可以跳一个台阶,也可以跳两个台阶。求该青蛙跳n个台阶共有多少种跳法?
例如:
输入:5 输出:8

解题思路青蛙跳台阶的思路是和斐波那契数的思路是完全等价的,只不过有了个主人公青蛙而已。因为青蛙跳1级台阶有一种走法,跳2级台阶有两种走法,而跳3级台阶有三种走法,所以跳3级台阶的走法是前面跳1级台阶和2级台阶之和,所以依次类推青蛙跳n个台阶的跳法等于跳n-1级台阶和n-2级台阶之和,所以问题就转变为求解第n个斐波那契数了。

walk(n)
walk(n-1) + walk(n-2)
walk(n-2)+walk(n-3) , walk(n-3)+walk(n-4)

一直递推下去,直至到walk(1)和walk(2)分别返回值为1和2,然后回归,得到青蛙跳n级台阶的跳法

代码实现
斐波那契数例题_第4张图片
斐波那契数例题_第5张图片
斐波那契数例题_第6张图片

3.经典问题之《汉诺塔问题》

题目描述:

总共有三个柱子,在一根柱子上,从下往上按照大小顺序摞着n片圆盘。我们需要按大小顺序重新摆放在另一根柱子上。并且规定,在移动过程,小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

解题思路:我们需要把圆盘看做一个个的整体,而且需要有大事化小的思想。假设我们有三根柱子:A,B,C(A:表示起始位置,B:表示中转站,C:表示目标位置

  1. 如果A柱有n=1个盘子,我们只要把它移动到C柱上就可以了。对应过程演示(1)。
  2. 如果A柱有n=2个盘子,则需先把A柱上第一个盘子放到B柱上 -> 再把A柱上第二个盘子(这时n=1)放到C柱上。对应过程演示(2)。
  3. 如果A柱有n=3个盘子,①.第一步:则需先把A柱上第一个盘子放到C柱上 -> 再把A柱上第二个盘子放到B柱上 -> 然后把C柱上的盘子放到B柱上面 -> 然后把A柱上第三个盘子(这时n=1)放到C柱上。②.第二步:再想办法把B柱上的圆盘移动到A柱上,先把B柱上第一个圆盘放到A柱上 -> 再把B柱上的圆盘放到C柱上 -> 最后再把A柱上的圆盘放到C柱上。对应过程演示(3)。

    如果A柱有n个盘子,步骤是一样的,肯定是先想办法把A柱上n-1个圆盘移动到B柱上 -> 之后才能想办法把第n个圆盘从A柱放到C柱上面(即n=1的时候,递归的限制条件) -> 最后想办法把B柱上的圆盘移动到C柱上面。对应过程演示(4)。

这里递归的限制条件是n=1
并且一定要注意:我们在解决汉诺塔问题时,一定不能太过于深究里面圆盘移动的过程,因为比较复杂,很容易让人绕进去。所以我们这里不考虑上述中的“想办法”(即移动的过程)
我们只要懂其中的原理就可以把汉诺塔实现出来,运用大事化小的思想

代码演示
斐波那契数例题_第7张图片
过程演示
(1)A柱上有1个圆盘:
斐波那契数例题_第8张图片
(2)A柱上有2个圆盘:
斐波那契数例题_第9张图片
(3)A柱上有3个圆盘:
斐波那契数例题_第10张图片
(4)A柱上有n个圆盘:
斐波那契数例题_第11张图片

总结

好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。
不积硅步,无以至千里;不积小流,无以成江海。

你可能感兴趣的:(C语言,kotlin,开发语言,android)