前中後序遍歷樹--遞歸非遞歸方法Java實現

import java.util.Stack;

class TreeNode {
     int val;
     TreeNode left;
     TreeNode right;
     TreeNode(int x) { val = x; }
}
public class Tree {

    //遞歸先序
    public void REPreOrder(TreeNode root) {
        if (root == null) return;
        System.out.println(root.val);
        REPreOrder(root.left);
        REPreOrder(root.right);
    }

    //非遞歸先序 棧中保存樹的右節點
    public void PreOrderA(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode p = root;
        while (p != null) {
            System.out.println(p.val);
            if (p.right != null) stack.push(p);
            if (p.left != null) p = p.left;
            else p = stack.pop();
        }
    }

    //非遞歸先序 棧中保存樹的左子樹
    public void PreOrderB(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                System.out.println(root.val);
                root = root.left;
            }
            if (!stack.isEmpty()) {
                root = stack.pop();
                root = root.right;
            }
        }
    }

    //遞歸中序
    public void REInOrder(TreeNode root) {
        if (root == null) return;
        REPreOrder(root.left);
        System.out.println(root.val);
        REPreOrder(root.right);
    }
    
    //非遞歸中序 棧中保存樹的左子樹
    public void InOrder(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            if (!stack.isEmpty()) {
                root = stack.pop();
                System.out.println(root.val);
                root = root.right;
            }
        }
    }

    //遞歸後序
    public void REPostOrder(TreeNode root) {
        if (root == null) return;
        REPreOrder(root.left);
        REPreOrder(root.right);
        System.out.println(root.val);
    }
    
    //非遞歸後序 增加標誌位棧
    /**
     * 1. 當root非空時循環:將root和標誌1壓入棧中,繼續遍歷左子樹
     * 2. 當棧非空且棧頂元素的標誌位爲2,輸出該元素
     * 3. 當棧非空將棧頂元素的標誌位改爲2(表示已經爲第二次遍歷),將root設置爲棧頂元素的右子樹
     * @param root
     */
    public void PostOrderA(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        //標誌棧
        Stack<Integer> flag = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                flag.push(1);
                root = root.left;
            }
            while (!stack.isEmpty() && flag.peek() == 2) {
                System.out.println(stack.pop().val);
                flag.pop();
            }
            //第二次遍歷到
            if (!stack.isEmpty()) {
                flag.pop();
                flag.push(2);
                root = stack.peek().right;
            }
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章