1. 程式人生 > >厚積而薄發,謀定而後動

厚積而薄發,謀定而後動

一、對比

相同點:

  • 遞迴和迭代都是迴圈的一種。

不同點:

      1、程式結構不同

  • 遞迴是重複呼叫函式自身實現迴圈。
  • 迭代是函式內某段程式碼實現迴圈。

        其中,迭代與普通迴圈的區別是:迭代時,迴圈程式碼中參與運算的變數同時是儲存結果的變數,當前儲存的結果作為下一次迴圈計算的初始值。

      2、演算法結束方式不同

  •  遞迴迴圈中,遇到滿足終止條件的情況時逐層返回來結束。
  • 迭代則使用計數器結束迴圈。

        當然很多情況都是多種迴圈混合採用,這要根據具體需求。

      3、效率不同

  • 在迴圈的次數較大的時候,迭代的效率明顯高於遞迴。(參見二中例項3)

 二、例項

1、遞迴:給定一個整數陣列,採用折半查詢返回指定值在陣列中的索引,假設陣列已排序,為方便描述,假設元素都為正數,陣列長度為2的整數倍。

int Find(int *ary,int index,int len,int value)
{
    if(len==1)//最後一個元素
    {
        if (ary[index]==value)return index;//成功查詢返回索引
        return -1;//失敗,返回-1
    }
    //如果長度大於1,進行折半遞迴查詢
    int half=len/2;
    //檢查被查值是否大於上半部分最後一個值,如果是則遞迴查詢後半部分
    if(value>ary[index+half-1])
        return Find(ary,index+half,half,value);
    //否則遞迴查詢上半部分
    return Find(ary,index,half,value);
}
2、迭代:實數累加,比如計算1-100所有實數的和。
int v=1;
for(i=2;i<=100;i++)
{
    v=v+i;
}
3、綜合應用(斐波那契數列分別用遞迴和迭代實現)

問題:如果兔子在出生兩個月後,就有繁殖能力,一對兔子每個月能生出一對小兔子,假設所有兔子都不死,那麼一年後可以繁殖出多少對兔子?


分析:前面相鄰兩項之和,構成了後一項。如圖,


數學定義:


程式碼實現:

#include "stdio.h"

int Fbi(int i)  /* 斐波那契的遞迴函式 */
{
	if( i < 2 )
		return i == 0 ? 0 : 1;  
    return Fbi(i - 1) + Fbi(i - 2);  /* 這裡Fbi就是函式自己,等於在呼叫自己 */
}  

int main()
{
	int i;
	int a[40];  
	printf("迭代顯示斐波那契數列:\n");
	a[0]=0;
	a[1]=1;
	printf("%d ",a[0]);  
	printf("%d ",a[1]);  
	for(i = 2;i < 40;i++)  
	{ 
		a[i] = a[i-1] + a[i-2];  
		printf("%d ",a[i]);  
	} 
	printf("\n");
	
	printf("遞迴顯示斐波那契數列:\n");
	for(i = 0;i < 40;i++)  
		printf("%d ", Fbi(i));  
    return 0;
}
執行結果:


執行過程顯示,在迴圈的次數較大的時候,迭代的效率明顯高於遞迴。上述例子中,筆者看到,迭代的結果全部列印完成耗時不到0.5s,而遞迴的結果前兩排列印完耗時在1s內,最後一排的每個資料列印越來越慢,特別是最後一個數據,待到倒數第二個列印後,約3-4s才打印出來。究其原因,大量的遞迴呼叫會建立函式的副本,會耗費大量的時間和記憶體。而迭代則不需要反覆呼叫函式和佔用額外的記憶體

轉載請註明出處:

http://blog.csdn.net/daijin888888/article/details/70157153