從葉子節(jié)點徹底理解二叉樹后序遍歷

二叉樹有前序,中序,后序三種遍歷順序。初學者很容易混淆。記住以下兩個關鍵點就很好理解。
三種順序的共同點:左右的順序是不變的。
三種順序的不同點:所謂的前中后序,說的是root節(jié)點的位置在前,中,后。先序是root,左,右;中序是左,root,右;后序的順序是左,右,中?;谝陨蟽牲c記憶就非常簡單了。

遞歸序的后序遍歷,即自定義的代碼邏輯在左右遞歸結束后執(zhí)行。通用的偽代碼框架結構如下:

public static int recursion(TreeNode node){

    if(node==null){
     return 0;
    }
    //前序遍歷 
    //代碼邏輯
    int left = recursion(node.left);
    //中序遍歷 代碼邏輯
    int right = recursion(node.left);
    //后序遍歷
    //代碼邏輯如下:
    return left+right+node.data; 
}

剛開始學遞歸,腦袋中一模擬方法中調用方法,腦袋就會炸鍋,瞬間感覺腦細胞不夠用了。其實可以換一個角度,放棄從root節(jié)點開始模擬,而是從最后一層葉子節(jié)點逆著模擬遞歸調用過程。

后序遍歷從執(zhí)行開始,代碼到 int left = recursion(node.left) 部分就會開啟新的壓棧,這個過程一直會持續(xù)到什么時候呢?答案是最終的葉子節(jié)點。

如果現(xiàn)在的入?yún)⑹侨~子節(jié)點,則node.left =null ,node.right=null 那么執(zhí)行遞歸函數(shù)后,都會返回0,即int left= 0,int right = 0;因為會判斷入?yún)閚ull,返回,不再繼續(xù)開啟新的堆棧了。
重點來了,跨過了前邊兩個坎兒

int left = recursion(node.left);
int right = recursion(node.left);

最終才會執(zhí)行到 return left+right+node.data部分,也就是自定義代碼這里。

葉子節(jié)點執(zhí)行完了,因為第一次調用這個方法的都是int left = recursion(node.left);所以會返回上一個堆棧記錄的地址,接著執(zhí)行上一個堆棧中的int right = recursion(node.left);以此往復,最終回到根結點root 再次執(zhí)行return left+right+node.data;

所以,后序遍歷的難點就是,只有到了葉子節(jié)點部分,才會完整執(zhí)行一次我們上邊寫的自定義代碼。其他部分都是只開堆棧,不執(zhí)行邏輯。

葉子節(jié)點時候,才會跳過左右繼續(xù)遞歸這兩個坎兒,第一次執(zhí)行返回操作。其他高一層級的調用,都是大爺,懶得要死,兒子不干完活兒返回結果,你休想叫醒他,讓他干一點活。但好處也是,一旦有返回結果了,他就自動執(zhí)行了。這就是后序遍歷的特點,高一級的依賴第低一級的返回結果。這么一說,有感覺了吧!

下邊這張圖展示了執(zhí)行順序


執(zhí)行順序圖.png

從root節(jié)點開始,一直執(zhí)行藍色的,直到最后一個藍色節(jié)點是null為止。返回到第二個藍色節(jié)點,執(zhí)行黃色點的遞歸方法,執(zhí)行完后,返回到當前的節(jié)點,即倒數(shù)第二個藍色節(jié)點,再返回,到達倒數(shù)第三個節(jié)點。。。以此類推
倒數(shù)第三個節(jié)點也是先執(zhí)行藍色,結束后回到黃色節(jié)點的方法體內,再執(zhí)行紅色遞歸調用,結束后再次回到黃色節(jié)點,執(zhí)行黃色節(jié)點的自定義代碼,之后再返回,達到倒數(shù)第三個節(jié)點

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容