1. 程式人生 > 實用技巧 >二叉樹先(中後)序非遞迴版

二叉樹先(中後)序非遞迴版

/*先序遍歷非遞迴方式
定義一個棧,將頭節點壓入棧中,當棧不為空時,彈出棧頂元素並儲存在list中,依次壓入右節點和左節點
 */
public static List<Integer> preorderTraversal(TreeNode root){
    List<Integer> res = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    if (root != null) {
        stack.push(root);
        while (!stack.empty()) {
            TreeNode treeNode = stack.pop();
            res.add(treeNode.val);
            if (treeNode.right != null) {
                stack.push(treeNode.right);
            }
            if (treeNode.left != null) {
                stack.push(treeNode.left);
            }
        }
    }
    return res;
}

/*中序遍歷非遞迴方式
定義一個棧,將二叉樹的左節點不斷壓入直到左節點不存在,然後依次彈出棧頂元素值並儲存在list中,並切換到右子樹
 */
public static List<Integer> inorderTraversal(TreeNode head){
    ArrayList<Integer> res = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    while (head != null || !stack.empty()) {
        if (head != null) {
            stack.push(head);
            head = head.left;
        }
        else{
            head = stack.pop();
            res.add(head.val);
            head = head.right;
        }
    }
    return res;
}

/*後續遍歷非遞迴方式
定義兩個棧,當頭節點不為空時,將頭節點壓入s1棧中,在棧s1不為空的迴圈體中,將s1棧頂節點彈出放入s2中,並將s1的左右節點依次壓入到
s1中,最後依次將s2中的節點值彈出儲存到list中即為後序遍歷的結果。
 */
public static List<Integer> postorderTraversal(TreeNode head){
    ArrayList<Integer> res = new ArrayList<>();
    Stack<TreeNode> s1 = new Stack<>();
    Stack<TreeNode> s2 = new Stack<>();
    if (head != null) {
        s1.push(head);
        while (!s1.empty()) {
            TreeNode treeNode = s1.pop();
            s2.push(treeNode);
            if (treeNode.left != null) {
                s1.push(treeNode.left);
            }
            if (treeNode.right != null) {
                s1.push(treeNode.right);
            }
        }
        while (!s2.empty()){
            res.add(s2.pop().val);
        }
    }
    return res;
}