1 if(root==null)
4 int left=maxdeepth(root.left);
5 int right=maxdeepth(root.right);
6 return left>right?left+1:right+1;
這是求樹的深度。那麼程式執行到第四行時,會不會先將left的遞迴呼叫壓入虛擬機器棧中繼續向下執行,一直到return。這個演算法的思想很簡單,但是結合到具體的執行原理,就講不清了。接下來是研究心得:
首先假設有這樣一棵樹:
程式從樹的根節點開始,第一次執行到left=maxdeepth(root.left)時,並沒有繼續向下,而是停在了這一句,它開始遞迴,此處不得不提虛擬機器棧的一部分知識:
1.在jvm棧中每呼叫一次方法就會做一次入棧操作,在棧中儲存為乙個棧幀(儲存方法的區域性變數,運算元棧,動態鏈結,方法返回位址和一些額外的附加資訊)。
2.在jvm棧中永遠都是底層棧幀呼叫上層棧幀。
假設棧幀就是乙個方法的副本(當然真正的遠比這複雜),不影響分析。
下面的每一次呼叫都會入棧產生棧幀,出棧產生結果給下一層棧幀。
那麼現在0節點入棧了,它執行到left這行,發現要呼叫乙個方法,才能拿到值,所以它根據條件向自己的左兒子節點1要個說法,節點1又向節點3要,3又向7要,7繼續向自己的左兒子要結果,但7的左兒子沒有是null,所以終於有了確切的結果,返回了0,所以在7這個方法副本中可以繼續向下走了,又找7的右節點要結果,這次不用費時間,右,兒子也乾淨利落的也給了它老子乙個0,7號節點所在的這層副本裡終於要產生自己最終結果了,7號在比較之後發現自己兒子們的最大身高是0,那麼加上7自己這1厘公尺的身高,就是全家的身高,所以返回了1,此時7這一家從jvm棧中出去了,它的下層副本就是節點3,那麼3這層副本呢,既然拿到了自己左兒子的準確身高,就可以向下走了,所以又去問自己的右兒子節點8,同樣的道理,8又將自己的左兒子入棧、出棧,之後將自己的右兒子入棧、出棧,獲得了自己的最大高度是1,節點3這層副本也就能從棧中出去了,它交出自己的結果給下層副本………………
到了這裡過程也就很清楚了,遞迴方法執行到需要遞迴的地方的時候,不會如**的過程一樣直接繼續執行,假設這層的**就是公式,jvm會去推理,術語叫做遞推,得到結果後又一層層把結果帶回來,術語叫回溯。這就好像是程式設計師告訴虛擬機器:去吧,皮卡丘,把勝利的果實帶回來,然乎皮卡丘又對自己的孩子說:去吧,皮卡丘,把勝利的果實帶回來…………然後最小的皮卡丘最終不負期望帶回了勝利,一層層把勝利傳遞回來給程式設計師。
python遞迴函式的執行過程
舉例 def nove n,a,b,c if n 1 print a,c else nove n 1,a,c,b nove 1,a,b,c nove n 1,b,a,c 執行輸出結果 nove 3,a b c a c a b c b a c b a b c a c 執行過程詳解 1 def nove...
對遞迴執行過程的簡單描述
include void fun int n int main 輸出結果為 分析1 主函式呼叫fun 1 2 此時n的值為1,隨即輸出第一行,並得到n的位址並將其抽象為aaaa 3 判斷,1 3,執行遞迴語句,重新執行fun函式 4 由於傳遞引數為n 1,所以本層n的值為2,隨即輸出第二行,並得到n...
遞迴的概念 函式遞迴過程
直接或間接地呼叫自身的演算法稱為遞迴演算法。用函式自身給出定義的函式稱為遞迴函式。使用遞迴技術往往會使 更簡潔,使演算法的描述更清晰且容易理解。例 1 階乘函式 階乘函式遞迴的定義為 當n 0時,n 1,這是這個函式的初始條件,是非遞迴定義的,是此遞迴函式的退出條件。這個遞迴函式在執行時,會不斷的呼...