1. 程式人生 > >演算法之美(斐波那契)

演算法之美(斐波那契)

演算法之美

資料結構 + 演算法 = 程式
資料結構是程式的骨架,演算法是程式的靈魂。

1.1 演算法複雜性

演算法是指對特定問題求解步驟的一種描述。

演算法特性
(1) 有窮性:演算法是若干條指令組成的有窮序列,總是在執行若干次後結束,不可能永不停止。
(2) 確定性:每條語句有特定的含義,無歧義。
(3) 可行性:演算法在當前環境條件下可以通過有限次運算實現。
(4) 輸入輸出:有零個或多個輸入,一個或多個輸出。

“好”演算法的標準
正確性、易讀性、健壯性、高效性、低儲存性。

時間複雜度:演算法需要執行的時間,一般將演算法的執行次數作為時間複雜度的度量標準。
空間複雜度

:算法佔用的空間大小,一般將演算法的輔助空間作為衡量空間複雜度的標準。

1.2 魔鬼序列

  • 棋盤麥子故事
    64 個格子共放 S = 1+2+2^ 2+……+2^63 ①
    把 ① 兩邊乘 2,
    2S=2+2^ 2+……+2^64 ②
    ② - ①:
    S = 2^64-1=18446744073709551615
    這樣的演算法稱為爆炸增量函式。

常見的演算法複雜度
(1)常數階,用 O(1) 表示。
(2)多項式階,用 O(n),O(n^ 2),O(n^3) 表示。
(3)指數階,用 O(2^ n),O(n!),O(n^n) 等表示。
(4)對數階,常見的有 O(logn),O(nlogn)。
關係:O(1)<O(logn)<O(n)<O(nlogn)<O(n^ 2)<O(n^ 3)<O(2^ n)<O(n!)<O(n^n)

  • 神奇兔子序列:當月的兔子數 = 上月兔子數 + 當月新生兔子數
    斐波拉契數列如下:
    1,1,2,3,5,8,13,21,34…
    遞迴表示式:
         	1              			,n=1
F(n)=  		1               			,n=2
      		F(n-1)+F(n-2)  			,n>2
  • 演算法設計:
Fib1(int n)
{
	if(n<1)
		return -1;
	if(n=1||n=2)
		return 1;
	return Fib1(n-1)+Fib1(n-2); 
}

時間複雜度分析

:這是一個指數階的演算法。當 n 趨於無限大時,這是一個爆炸增量函式。
演算法改進:

Fib2(int n)
{
	int i,s1=1,s2=1;
	if(n<1)
		return -1;
	if(n==1||n==2)
		return 1;
	for(i=3;i<=n;i++)
	{
		s2=s1+s2;//輾轉相加法
		s1=s2-s1;//記錄前一項
	}
	return s2;
}

複雜度分析:時間複雜度為 O(n),空間複雜度為 O(1) ;