Java-斐波拉契數列的三種實現方法


先看下百度百科對斐波拉契數列的定義:

          斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列: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*) 反正就是一句話:斐波拉契牛逼。

 

第一種數組實現方法:基於數組實現

 

 

/**
 * @author 薛定諤的貓
 * 斐波拉契數列數組實現
 * 求前二十項*/
public class Main {
	public static void main(String[] args) {
		getFib(20);
	}
	
	public static int getFib(int n){//核心函數
		if (n<0) {
			return -1;//小於0是沒有意義的
		}else if (n == 0) {
			return 0;//等於0其實也沒什么意義
		}else if (n == 1||n == 2) {
			return 1;//第一項和第二項都是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];//當前項等於后一項加上后兩項
				System.out.println("第" + i + "項"+fibAry[i]);//輸出當前項
			}
			return fibAry[n];//返回當前項
		}
	}
}

 

  

 

第二種實現方法:基於變量實現

 

/**
 * @author 薛定諤的貓
 * 斐波拉契數列變量實現
 * 求前二十項*/
public class Main {
	public static void main(String[] args) {
		getFib(20);
	}
	
	public static int getFib(int n){//核心函數
		if (n<0) {
			return -1;//小於0是沒有意義的
		}else if (n == 0) {
			return 0;//等於0其實也沒什么意義
		}else if (n == 1||n == 2) {
			return 1;//第一項和第二項都是1
		}else {
			int temp = 0;//當前項變量
			int a = 1;//第一項
			int b = 1;//第二項
			
			for(int i = 3;i<=n;i++) {
				//變量互換值
				temp = a+b;//當前項等於前兩項相加
				a = b;//前兩項互換值
				b = temp;//當前項賦值給前一項
				System.out.println("第" + i + "項"+temp);//輸出當前項
			}
			return temp;//返回當前項
		}
	}
}

  

 

第三種實現方法:遞歸實現(用遞歸的都是神)

        遞歸定義:簡單的說就是自己調用自己。

 

/**
 * @author 薛定諤的貓
 * 斐波拉契數列變量實現
 * 求前二十項
 * 這種方法最簡單,但是最占用內存,特別是當n很大的時候
 * 
 * 
 * 為什么遞歸得效率低?
 * 遞歸效率低是函數調用的開銷導致的。在一個函數調用之前需要做許多工作,
 * 比如准備函數內局部變量使用的空間、搞定函數的參數等等,這些事情每次調用函數都需要做
 * ,因此會產生額外開銷導致遞歸效率偏低,所以邏輯上開銷一致時遞歸的額外開銷會多一些當然了,
 * 通過有意識的組織代碼的寫法可以把某些遞歸寫成尾遞歸,尾遞歸可以進行特殊的優化所以效率
 * 會比普通的遞歸高一些,也不會因為遞歸太多導致棧溢出遍歷樹還不用遞歸的話,那么人肉寫一個棧
 * +深度優先遍歷或者人肉隊列+廣度優先遍歷,再輔以黑魔法給棧或者隊列提速,應該會比遞歸快一些,
 * 加速幅度和語言和寫法相關,但在大多數情況下我覺得是得不償失的,花了很大精力很可能效率提升不
 * 明顯
 * 
 * 此回答轉自知乎

 * */
public class Main {
	public static void main(String[] args) {
		for(int i = 1;i<=20;i++) {
		System.out.println("第" +i + "項" + getFib(i));
		}
	}
	
	public static int getFib(int n){//核心函數
		if (n<0) {
			return -1;//小於0是沒有意義的
		}else if (n == 0) {
			return 0;//等於0其實也沒什么意義
		}else if (n == 1||n == 2) {
			return 1;//第一項和第二項都是1
		}else {
				return getFib(n-1) + getFib(n-2);//返回當前項,核心遞歸
			}
		}
	}

  

 

最后說一句,斐波拉契牛逼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM