遞歸與循環:
-
同樣的操作,在遞歸中執行的效率要低於循環中執行的效率,因爲遞歸要進行地址的保存,和入棧操作。
2.遞歸與循環是可以相互轉換的
由於這點有時爲了程序的效率需要把遞歸轉換成循環:有如下幾種常見的轉換情形:
-
尾部遞歸:尾部遞歸是指在一個函數中遞歸出現在最後,此時遞歸併不需要維持局部變量所以可以放心轉換成循環形式。轉換方式爲把尾部遞歸的遞歸條件變成循環條件然後套在整個函數的外面,最後把對參數的操作放在循環中。如下所示:
void f(n) {
if(n>0)
{
f(n+1);
f(n-1); //尾部遞歸 對參數減一
}
}
void f(n) {
while(n>0)//遞歸條件改爲循環條件
{
f(n+1);
n--; //同樣對參數的減一
}
}
-
第二種需要進行遞歸消除的是遞歸樹爲一條鏈的時候:
此時就是說函數中的遞歸只有一個。這個時候可以把遞歸轉換爲迭代循環。如下程序所示。
int f(n){
if(n == 0){
return 0;
}
if(n>0){
return n+f(n-1);
}
return sum;
}
int f(n){
int sum = 0;
while(n>0){
sum = n+1;
n--;
}
return sum;
}
還有其他的遞歸同樣可以轉換,有的轉換爲循環可能難度較大,此時可以轉化爲棧的形式,用入棧出棧模擬函數調用,同樣可以提高效率。