一、介绍
什么是斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列 ,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以递推的方法定z义:F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。言简意赅就是后一个数是前两个数的和。
有如下公式:
解释说明为:
如果每对兔子(一雄一雌)每月能生殖一对小兔子(也是一雄 一雌),每对兔子第一个月没有生殖能力,但从第二个 月以后便能每月生一对小兔子。假定这些兔子都没有死亡现象,那么从第一对刚出生的兔子开始,12 个月以后会有多少 对兔子呢?
一个月 :只有一对兔子;
第二个月: 仍然只有一对兔子;
第三个月:这对兔子生了一对小兔子, 共有 1+1=2 对兔子;
第四个月:最初的一对兔子又生一对兔 子,共有 2+1=3 对兔子.
......
则由第一个月到第十二个月兔子的 对数分别是:1,1,2,3,5,8,13,21,34,55,89,144, ……,后人为了纪念提出兔子繁殖问题的斐波纳契, 将这个兔子数列称为斐波那契数列, 即把 1,1,2,3,5,8,13,21,34……这样的数列称为斐波那契数列。
图像解释:
形象一点,可以将其理解为如下的螺旋
拓展:
斐波那契数列有通项公式
推导比较麻烦,对数学感兴趣的同学可以自己查查资料看看。
二、思路
1.递归:
递归就是自己调用自己。从公式可以轻易看出从第三项开始,后一项都是前两项之和,符合递归条件。
2.迭代:
和递归一样,迭代也是循环的一种,迭代是函数内某段代码实现循环。而迭代与普通循环的区别是:循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。
3.数组:
因为数组有下标,可以将其当作数列的项数,此方法的实现有些类似于递归。
三、代码实现
递归
//方法一:递归
#include<stdio.h>
int Fibo(int n)
{
if (n == 1 || n == 2) //数列前两项为1
return 1;
else //从第三项开始
return Fibo(n - 1) + Fibo(n - 2);
}
int main()
{
int n, i;
printf("请输入数列的个数:\n");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
printf("%12d", Fibo(i)); //控制输出格式
if (i % 4 == 0) //控制一行输出四个
printf("\n");
}
return 0;
}
这个是按照函数定义去实现的,比较容易理解。
迭代
#include<stdio.h>
int Fibo(int n)
{
int f1 = 1,f2 = 1,f3 = -1,i=0;
for (int i = 3; i <= n; i++)
{
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
if (n == 1 || n == 2)
return 1; //前两项为1
else
return f3; //将f3赋值给数列
}
int main()
{
int n, i;
printf("请输入数列的个数:\n");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
printf("%12d", Fibo(i)); //控制输出格式
if (i % 4 == 0) //控制一行输出四个
printf("\n");
}
return 0;
}
这里我们可以看到在代码实现上方法一其实是更简便的,但是其存在栈溢出的问题,对于新手我们可以先不用考虑这个问题。
数组
//数组法
#include<stdio.h>
int Fibo(int n)
{
int i;
int arr[100] = { 0,1,1 };
for (i = 2; i <= n; i++) //从第一项开始
{
arr[i] = arr[i - 1] + arr[i - 2]; //注意数组是从0开始为下标的
}
return arr[n];
}
int main()
{
int n, i;
printf("请输入数列的个数:\n");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
printf("%12d", Fibo(i)); //控制输出格式
if (i % 4 == 0) //控制一行输出四个
printf("\n");
}
return 0;
}
因为数组的下标是从0开始的,因此不要像递归法一样讨论第一项和第二项的特殊情况,更为方便。
运行结果
三种方法运行结果都一样
四、总结
继续学习研究,还会发现有更多的方法表示斐波那契数列。研究数列本身也会发现,数列有许多值得探索的地方,其乐无穷。
宝剑锋从磨砺出,梅花香自苦寒来