[java] 二叉樹的後序遍歷(遞迴與非遞迴實現)

VictorLeeLk發表於2017-08-29

後序遍歷遞迴定義: 先左子樹,後右子樹,再根節點。

後序遍歷的難點在於:需要判斷上次訪問的節點是位於左子樹,還是右子樹。

若是位於左子樹,則需跳過根節點,先進入右子樹,再回頭訪問根節點;

若是位於右子樹,則直接訪問根節點。直接看程式碼,程式碼中有詳細的註釋。
這裡寫圖片描述

public void behindOrder(Tree n){
        if(n!= null){
            behindOrder(n.left_child);
            behindOrder(n.right_child);
            System.out.print(n.val+" ");
        }
    }


        /**
         * public class Node {
            public int data; //樹結點標號
            public Node lchild; //左子樹
            public Node rchild;  //右子樹
        }
        後序遍歷遞迴定義:先左子樹,後右子樹,再根節點。
        後序遍歷的難點在於:需要判斷上次訪問的節點是位於左子樹,還是右子樹。
            若是位於左子樹,則需跳過根節點,先進入右子樹,再回頭訪問根節點;
            若是位於右子樹,則直接訪問根節點。
         */

        public void behindOrder2(Tree node){
            if(node==null)
                return;
            Stack<Tree> s = new Stack<Tree>();

            Tree curNode; //當前訪問的結點
            Tree lastVisitNode; //上次訪問的結點
            curNode = node;
            lastVisitNode = node;

            //把currentNode移到左子樹的最下邊
            while(curNode!=null){
                s.push(curNode);
                curNode = curNode.left_child;
            }
            while(!s.empty()){
                curNode = s.pop();  //彈出棧頂元素
                //一個根節點被訪問的前提是:無右子樹或右子樹已被訪問過
                if(curNode.right_child !=null && curNode.right_child != lastVisitNode){
                    //根節點再次入棧
                    s.push(curNode);
                    //進入右子樹,且可肯定右子樹一定不為空
                    curNode = curNode.right_child;
                    while(curNode!=null){
                        //再走到右子樹的最左邊
                        s.push(curNode);
                        curNode = curNode.left_child;
                    }
                }else{
                    //訪問
                    System.out.print(curNode.val+" " );
                    //修改最近被訪問的節點
                    lastVisitNode = curNode;
                }
            } //while
        }

相關文章