厚積而薄發,謀定而後動
阿新 • • 發佈:2019-02-18
一、對比
相同點:
- 遞迴和迭代都是迴圈的一種。
不同點:
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