1. 程式人生 > >[計算機程式設計C++] Fibonaci數列的遞迴與非遞迴演算法實現

[計算機程式設計C++] Fibonaci數列的遞迴與非遞迴演算法實現

本文是對西安交通大學C++慕課第三章程式設計練習的16題的講解。
參考部落格:https://blog.csdn.net/zombie_slicer/article/details/38871799

題目內容:

編寫程式,顯示Fibonaci序列的前n項(從0開始)。

F(0)=0 F(1)=1 F(n)=F(n-1)+F(n-2)

輸入:非負整數n

輸出:n+1個整數,資料間有一個空格,末尾無空格。

【提示】

樣例1輸入:

10

樣例1輸出:

0 1 1 2 3 5 8 13 21 34 55

時間限制:500ms     記憶體限制:32000kb


Fibonaci數列:

當輸入正整數n為0或1時,f(0)=0,f(1)=1;當n大於1時f(n)=f(n-1)+f(n-2)。

一種非常簡單的實現方式是通過遞迴演算法:

int function(int n)
{
	if (n == 0)
	{
		return 0;
	}
	else if (n == 1)
	{
		return 1;
	}
	else if(n>=2)
	
	return function(n - 1) + function(n - 2);
}

通常來說,聽到Fibonaci首先想到的就是遞迴,但是這並不能說明遞迴最適合這個題目。例如,要算f(10), 首先要分別求f(9)和f(8);同樣,要算f(9),就得先算f(8)和f(7); 以此類推…

利用遞迴演算法求Fibonaci數列會出現大量的重複計算,把這個結構畫成二叉樹,可以看出當n越大,重複的節點數將急劇增大,計算量也因此大大增加,實際上,此演算法的時間複雜度是以n的指數的方式增加的。

比如這道題目限制程式執行時間在500ms 以內,使用遞迴演算法求解就會出現執行超時的錯誤 (親測)。

另一種實現方式是通過迴圈的方式。

大致思想為:從底到上計算,即先根據f(0)和f(1)計算出f(2),再通過f(1)和f(2)計算出f(3),以此類推,直到f(n)為止。從而避免大量的重複計算,其時間複雜度為O(n)。程式碼如下:

int function(int n)
{
	long
long first = 0; long long second = 1; long long sum = 0; if(n<=1){ return (n==1)? 1:0; } for(int i=2; i<=n;i++){ sum = first + second; first = second; second = sum; } return sum; }

本題的完整程式碼如下:

#include<iostream>
#include<stdlib.h>
using namespace std;
int function(int n);
int main()
{
	int i,n;
	cin >> n;
	for (i = 0; i <= n; i++)
	{
		cout << function(i);
		if (i < n)
		{
			cout << " ";
		}
	}
	cout << endl;
	return 0;
}



int function(int n)
{
	long long first = 0;
	long long second = 1;
	long long sum = 0;
	
	if(n<=1){
		
		return (n==1)? 1:0;
	}
	
	
	for(int i=2; i<=n;i++){
		
		sum = first + second;
		first = second;
		second = sum;
	}
	return sum;
}