遞歸的參數和返回值


  一個函數只能有一個返回值,具有返回值的遞歸函數若平行的多次調用自身,那么將會產生多個返回值,這是一個bug。在樹形多分枝結構的遞歸中對兩種方式進行比較討論。

例如求樹高的兩種寫法:

 1 struct Node{
 2     int val;
 3     Node* child;
 4     Node* sibling;
 5     Node(){
 6         child=NULL;
 7         sibling=NULL;
 8     }
 9 }; 
10 int height(Node *root){
11     if(root){
12         int maxh=0;
13         for(Node *p=root;p;p=p->sibling){
14             int tmp=height(p->child);
15             if(maxh<tmp){
16                 maxh=tmp;
17             }
18         }
19         return maxh+1;
20     }
21     return 0;
22 }

 

 1 int maxh=0;
 2 void height(Node *root,int h){
 3     if(root){
 4         for(Node* p=root;p;p=p->sibling){
 5             height(p->child,h+1);
 6         }
 7     }else{
 8         if(maxh<h){
 9             maxh=h;
10         }
11     }
12 } 

  前者使用帶有返回值的遞歸形式,利用返回值進行計算;后者采用傳參的形式,利用參數進行計算。之所以能有這兩種寫法,是因為樹高要求每條路徑的最深,再進行比較,是到最深處才能確定的。也是唯一的解。而其除了這些有唯一解的遞歸問題,例如遞歸建立二叉樹的多分枝層次問題等,就很難使用帶有返回值的遞歸求解。帶有返回值的遞歸,由淺入深,在最深處達到出口進行計算后能逐層返回淺層。注意返回,這就需要返回一個唯一確定的值了。

 p.s.說明一下何為唯一,遞歸到最深層后,逐層向淺層返回值,必有確定的一條路徑,稱為唯一。

  一個關鍵性的點--具象的多分枝遞歸是一個怎樣的過程,前面的文章中提到過多分枝的遞歸問題生成樹形結構。故具體的可以參考圖的深度優先遍歷,遞歸是以一條路走到黑,走不動再返回分岔口再選擇另一條路,最終遍歷多分枝的所有路徑的方法,類似我們走迷宮的暴力解法。每條路徑不能直接進行傳值等交互操作但是,但我們可以選擇路徑,選擇符合我們條件的路徑的結果。對比於圖的廣度優先遍歷,可以說深度,也就是遞歸的方式是一個線性化的路線,只能父子節點進行交互,兄弟節點在不同的路徑上故被隔離了;而層次遍歷則一次可以訪問所有的節點,也就產生了兄弟節點的關聯。

 

  下面討論剛才提到的難以寫成帶有返回值的遞歸的問題。

  多分枝層次問題:

  建立樹,例如二叉樹有兩種形式,一種是層次建立,不在本次遞歸的主題中討論;另一種是遞歸建立,對於每個節點,先建立根節點,再建立左右子樹。算法生成的樹的順序即和先序遍歷相同,也是“線性”地產生了二叉樹。這個多分枝問題直到最深處二叉樹建立完畢就結束了,並沒有向淺層返回的確定的路徑(值。

addition:求樹的路徑數(二叉樹,樹自己寫循環

1   int paths(node root){
2         if(root!=null){
3             if(root.left==null&&root.right==null)
4                 return 1;
5             return paths(root.left)+ paths(root.right);
6         }
7         return 0;
8     }

 


免責聲明!

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



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