斐波那契数列的定义
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
百度百科关于斐波那契数列的来源请参见兔子问题根据其定义我们可以很方便的构建出该数列的数据结构实现。
实现方法
实现一:基于递归形式实现
这种写法是最常见的,但是可能会造成栈溢出(每一次方法调用,都会有一个栈帧),这个方法不是很好,因为有大量的重复计算
/**
* 返回斐波那契数第n个值,n从0开始
* 实现方式,基于递归实现
* @author zxy
* @since 2018年8月18日上午9:41:30
*/
public static int getFib(int n){
if(n < 0){
return -1;
}else if(n == 0){
return 0;
}else if(n == 1 || n ==2){
return 1;
}else{
return getFib(n - 1) + getFib(n - 2);
}
}
递归是最简单的实现方式,但递归有很多的问题,在n的值非常大时,会占用很多的内存空间
递归的主要缺点
- 会有很多的重复计算,占用大量的内存空间
- 可能造成栈溢出
既然该数列定义F(n)=F(n-1)+F(n-2)(n≥2,n∈N*),那么我们可以从头到尾进行计算,先计算前面的值,然后逐步算出第n个值。
基于变量形式实现
使用循环的方式去解决,避免的递归的重复计算
/**
* 返回斐波那契数第n个值,n从0开始
* 实现方式,基于变量实现
* @author zxy
* @since 2018年8月18日上午9:41:30
*/
public static int getFib2(int n){
if(n < 0){
return -1;
}else if(n == 0){
return 0;
}else if (n == 1 || n == 2){
return 1;
}else{
int c = 0, a = 1, b = 1;
for(int i = 3; i <= n; i++){
c = a + b;
a = b;
b = c;
}
return c;
}
}
从上面的实现中我们定义了3个变量a、b、c其中c=a+b,然后逐步进行计算从而得到下标为n的值。
既然我们可以定义变量进行存储,那么同样我们还可以定义一个数组,该数组的每一个元素即一个斐波那契数列的值,这样我们不仅能得到第n个值,还能获取整个斐波那契数列。
基于数组的实现
以空间换时间
/**
* 返回斐波那契数第n个值,n从0开始
* 实现方式,基于数组实现
* @author zxy
* @since 2018年8月18日上午9:41:30
*/
public static int getFib3(int n){
if(n < 0){
return -1;
}else if(n == 0){
return 0;
}else if (n == 1 || n == 2){
return 1;
}else{
int[] fibAry = new int[n + 1];
fibAry[0] = 0;
fibAry[1] = fibAry[2] = 1;
for(int i = 3; i <= n; i++){
fibAry[i] = fibAry[i - 1] + fibAry[i - 2];
}
return fibAry[n];
}
}
还有一种写法是,是使用hashMap将数据都存储下来,hashMap的写法其实类似于上面的数组形式,就不单独写出来了