[計算機程式設計C++] Fibonaci數列的遞迴與非遞迴演算法實現
阿新 • • 發佈:2018-11-05
本文是對西安交通大學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;
}