遞歸調用語句前后的語句


void show(....)
{    
   ...
   show(....);
   ...    
}

在上面這個遞歸函數中,調用自己的那行語句叫作遞歸調用語句。

有時候,遞歸調用的前后往往還有其他語句,它們的執行順序情況是有規律的。

 

考慮一個數組 int a[7],設當前位置在a[6],並希望以遞歸的方式輸出數組內容(沒人會用遞歸做這種事情)。

int main(int argc, char* argv[])
{
  int a[7] = {1,2,3,4,5,6,7};
  // show(a, 6);
  show(a, sizeof(a) / sizeof(int) - 1);
  cout<<endl;
  return 0;
}

 

如果我的輸出語句寫再遞歸調用的前面,如:

void show(int* a, unsigned i)
{
    if(i == 0)
    {
        cout<<a[i]<<" "return;
    }
    cout<<a[i]<<" ";  
    show(a, i - 1);
}

則輸出為:7 6 5 4 3 2 1。

 

而如果我的輸出語句寫在遞歸調用的后面,如:

void show(int* a, unsigned i)
{
  if(i == 0)
  {
    cout<<a[i]<<" ";
    return;
  }
  show(a, i - 1);
  cout<<a[i]<<" "; 
}

則輸出為:1 2 3 4 5 6 7。

 

可見,在遞歸調用語句前后的語句,最終執行的順序是反過來。

 

考慮第一種情況。一開始位置在a[6],則a[6]在遞歸調用之前就已經輸出了 。

進入遞歸,當前位置在a[5],可發現a[5]在遞歸調用之前也已經輸出了。

再進入遞歸,當前位置a[4],也在遞歸調用之前輸出了.....

這樣,先輸出的永遠是當前位置的元素,a[0]將會被最后輸出。

 

第二種情況中,總是在遞歸調用后才輸出當前元素,所以當前元素永遠是后輸出的。

 

再觀察代碼,第一種情況:

  cout<<a[i]<<" ";

  show(a, i - 1);

因為i相關的語句在前面,i-1 相關的語句在后面,所以是先處理 i 相關的,再處理 i-1 相關的。

 

反之第二種情況:

  show(a, i - 1);

  cout<<a[i]<<" ";

先處理 i-1 相關的, 再處理 i 相關的。

 

可見,執行語句放在遞歸調用的前面還是后面,是個很重要的問題。雖然上面這個例子完全可以不用遞歸來完成,但說明了一些道理。

 

假設要寫一個程序,來完成類似linux中pwd命令的功能,以輸出當前目錄的完整路徑,那么上面例子揭示的道理就很有用了。

每一級目錄的名字就好比是數組a中的每一個元素。

如此看來,需求不過就是:當前位置在a的最后一個元素,而要把數組a的所有元素從前往后輸出。

所以,輸出每個目錄名的語句必須放到遞歸調用語句的后面。

 

參考資料:

《Unix/Linux編程實踐教程》 - (美) Bruce Molay 著,楊宗源/黃海濤 譯 - 清華大學出版社


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM