徹底理解遞迴,從遞迴的本質說起!
遞迴呼叫的特殊性在於自己呼叫自己,給人一種迷茫感,如果是遞迴呼叫“一次”,那還相對好理解,比如求階乘的遞迴演算法,
- int F(int n)
- {
- if(n==0)//遞迴邊界
- return 1;
- return n*F(n-1);//遞迴公式
- }
一層一層呼叫,知道遞迴結束條件成立,再一層一層返回;但如果像二叉樹是遞迴呼叫“兩次”,似乎理解起來就不是很容易了。
- void preorder(bintree t){
- if(t){
- printf("%c ",t->data);
- preorder(t->lchild);
- preorder(t->rchild);
- }
- }
對於一顆如下的二叉樹,它的前序遍歷順序該怎麼理解呢?我們今天來好好理一遍它的過程。
可以把遞迴看成是自己呼叫另一個和自己功能一樣,但是函式名不同的函式來理解,或許看得更清楚明白,下面我們來看看這個前序遍歷的過程是怎樣的。
首先,我們記上面這個函式為F1,表示外層的函式,內層函式表示下一層的函式,也就是第二層的F2,依次類推。
那從F1依次呼叫直到F3,注意這個時候都是在左子樹就是L的呼叫,所以依次列印出“A B D ”,這都沒什麼問題,就是普通函式呼叫。F3呼叫F4的時候,記得我們層函式的最前面是遞迴的退出條件,也就是空子樹就返回,由於D的左子樹是空,所以到這裡F4會返回到F3,即返回到L之後,R之前。
接在,在F3層,從R開始繼續呼叫F4,即開始訪問D的右子樹,此時列印出“F”,然後呼叫F4的左子樹,也就是呼叫F5函式,當然是空,所以返回到F4,再呼叫F4的右子樹,也是空,所以也是返回到F4,此時F4這一層已經全部呼叫完成,所以繼續向上返回到F3,記得我們之前是怎麼下來的嗎,就是從F3的右子樹開始訪問,所以F3層函式也已經呼叫完成,繼續往上返回到F2。
繼續呼叫F2的右子樹,也就是呼叫F3函式,此時列印出“E”,接著再訪問E的左右子樹,都是空,所以返回到F2,F2層函式已經全部呼叫完成。返回到F1,也就是A的左子樹部分全部訪問完成,此時開始訪問A的右子樹,列印出“C”,再推下去就是依次列印“G”和“H”。至此,整顆二叉樹節點前序遍歷完成,順序就是“A B D F E C G H”。
二叉樹是一種遞迴定義的資料結構,所以用遞迴來寫它的相關演算法是順理成章的,只是有時候覺得需要稍微理解一下這個過程,這個就是我的理解方法。
---------------------
作者:allenchenhh133
來源:CSDN
地址:https://blog.csdn.net/allenchenhh133/article/details/80291252
相關文章
- 理解遞迴遞迴
- SQL Server中CTE的另一種遞迴方式-從底層向上遞迴SQLServer遞迴
- 理解遞迴 Recurtion遞迴
- 遞迴函式的理解遞迴函式
- 人腦理解遞迴遞迴
- 遞迴和尾遞迴遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- 用 JavaScript 的方式理解遞迴JavaScript遞迴
- 遞迴思想的巧妙理解遞迴
- 遞迴遞迴
- ACM(遞迴遞推—A)ACM遞迴
- 圖形輔助,理解遞迴遞迴
- Java學習之理解遞迴Java遞迴
- 從漢諾塔遊戲理解python遞迴函式遊戲Python遞迴函式
- ACM(遞迴遞推—I)ACM遞迴
- JavaScript遞迴JavaScript遞迴
- go 遞迴Go遞迴
- 遞迴 Java遞迴Java
- 我對遞迴的理解和總結遞迴
- 我對Postgresql遞迴查詢的理解SQL遞迴
- 遞迴 & 分治演算法深度理解遞迴演算法
- 直觀理解(尾)遞迴函式遞迴函式
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 遞迴和遞推總結遞迴
- 函式的遞迴函式遞迴
- JavaScript中的遞迴JavaScript遞迴
- 演算法小專欄:遞迴與尾遞迴演算法遞迴
- 迭代與遞迴--你被遞迴搞暈過嗎?遞迴
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- Vue3.0的遞迴監聽和非遞迴監聽Vue遞迴
- 從“數學歸納法”到理解“遞迴演算法”!遞迴演算法
- 從紅黑樹的本質出發,徹底理解紅黑樹!
- 遞迴函式遞迴函式
- 遞迴-*快速排序遞迴排序
- sql server遞迴SQLServer遞迴
- C#遞迴C#遞迴
- Vue元件遞迴Vue元件遞迴
- javascript遞迴整理JavaScript遞迴