斐波那契数列——递归与迭代方法,及青蛙跳台阶求解

一.函数递归?

1.递归是什么?

  • 说白了递归就是函数自己调用自己。以下一个简单的递归。
#include<stdio.h>
int main()
{
	printf("hehe\n");
	main();
	return 0;
}

在这里插入图片描述
代码最终会陷⼊死递归,导致栈溢出(Stack overflow)。

2.递归的思想

  • 递归的思考方式就是把大事化小的过程。递归中的递就是递推的意思,归就是回归的意思。

递归在书写的时候,有2个必要条件:

  • 递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。

  • 每次递归调用之后越来越接近这个限制条件。

二.第n个斐波那契数

1.什么是斐波那契数列

斐波那契数列(Fibonacci sequence):也被称为黄金分割数列,是一个著名的数列,由意大利数学家莱昂纳多·斐波那契所提出。这个数列的特点是从第三项开始,每一项都等于前两项之和。斐波那契数列的前几个数是:1、1、2、3、5、8、13、21、34等。这个数列在自然界中很常见,比如花的萼片和花瓣数量,以及某些植物的叶子排列,常常遵循这一规律。斐波那契数列也被应用于工程技术、科学计算、艺术创作等多个领域。

2.递归求解第n个斐波那契数

  • 通过对斐波那契数列的了解,得出通项公式:

在这里插入图片描述

#include<stdio.h>
int Fib(int n)
{
	if (n == 1 || n == 2)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}
int main()
{
	int ret = Fib(8);
	printf("%d\n", ret);//输出21
	return 0;
}

3.迭代求解第n个斐波那契数

  • 迭代也就是我们通常所说的循环,即用循环的方法来求第n个斐波那契数:
int Fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 0;
	while (n - 2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main()
{
	int ret = Fib(8);
	printf("%d\n", ret);//输出21
	return 0;
}

4.递归与迭代的优缺点

  如果仅仅从代码量上看,递归所写的代码少,简洁。但这能说明递归的效率高吗?其实不然,当你要求第50个斐波那契数的时候,你会发现递归迟迟给不出运行结果,而迭代秒出结果,就算是第100,1000,10000个斐波那契数,都是秒出结果。那这是什么原因呢?

  其实,在递归法中,我们要求第50个斐波那契数,就要先求第49个和第48个斐波那契数,而要求第49个斐波那契数,又要先求第48个和第47个斐波那契数,要求第48个斐波那契数,就要先求第47个和第46个斐波那契数… 你会发现求出的结果任然要再求一遍,甚至第3,4,5…遍,导致递归效率非常低。而迭代只需一遍,效率远高于递归。

在这里插入图片描述

  • 由此看出递归做了很多无用功,例如给出计算Fib(1)运行了多少次:
#include<stdio.h>
int count = 0;
int Fib(int n)
{
	if (n == 1)
		count++;
	if (n == 1 || n == 2)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}
int main()
{
	Fib(50);
	printf("count=%d\n", count);
	return 0;
}

  输出count=317811,这个数字已经很大了,当要求第50个斐波那契数的时候,计算机在不停的重复计算,导致迟迟出不了结果,这正是递归效率低的原因。

三.青蛙跳台阶问题

在这里插入图片描述

  青蛙跳台阶:已知青蛙一次能跳一个或两个台阶,问青蛙跳到第50个台阶有多少种方法。

问题分析:

  • 当青蛙要跳到第1个台阶时:只需一次跳一个台阶,有1种方法
    Func(1)=1
  • 当青蛙要跳到第2个台阶时:可以两次跳一个台阶,一次跳两个台阶,有2种方法
    Func(2)=2
  • 当青蛙要跳到第3个台阶时:有两种情况:1.先跳一个台阶,青蛙要跳到第2个台阶的方法 2.先跳两个台阶,青蛙要跳到第1个台阶的方法。Func(3)=Func(2)+Func(1)=3
  • 当青蛙要跳到第4个台阶时:有两种情况:1.先跳一个台阶,青蛙要跳到第3个台阶的方法 2.先跳两个台阶,青蛙要跳到第2个台阶的方法。Func(4)=Func(3)+Func(2)=5
  • 当青蛙要跳到第n个台阶时:有两种情况:1.先跳一个台阶,青蛙要跳到第n-1个台阶的方法 2.先跳两个台阶,青蛙要跳到第n-2个台阶的方法。
    Func(n)=Func(n-1)+Func(n-2)

  看到这里,你也许就豁然开朗了,其青蛙跳台阶就是典型的斐波那契数列问题,给出递归代码:

int Func(int n)
{
	if (n == 1)
		return 1;
	else if (n == 2)
		return 2;
	else
		return Func(n - 1) + Func(n - 2);
}
int main()
{
	int ret = Func(20);
	printf("%d\n", ret);
	return 0;
}
  • 32
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值