二叉樹的遍歷 迭代 LeetCode 94 144 145

這裏簡要介紹一下樹的迭代方式遍歷


前序遍歷 leetcode 94
使用棧來模擬遞歸,出棧時候訪問結點。前序遍歷先訪問左子樹,再訪問右子樹,那麼入棧時相反,即先入右子樹,再入左子樹。那麼出棧的時候就是前序遍歷的順序。


class PreOrder {
    ArrayList<Integer> result = new ArrayList<>(); 
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        if ( root!=null ) {
            TreeNode cur = null; 
            Stack<TreeNode> s = new Stack<>(); 
            s.push(root);
            while ( !s.isEmpty() ) {
                cur = s.pop();
                result.add(cur.val);
                if( cur.right!=null ) {
                    s.push(cur.right);
                }
                if ( cur.left!=null ) {
                    s.push(cur.left); 
                }
            }
        }
        return result; 
    }
}

後序遍歷 LeetCode 145
後序遍歷是 左 右 中。同前序遍歷一樣,也是在出棧的時候訪問數據。我們先將所有左子樹的左結點加入到棧中,每pop出一個結點,意味這個結點的左子樹已經被訪問完畢。所以我們只考慮右子樹的情況。
當右子樹爲空,那麼此結點可以訪問。
當右子樹非空,1) 右子樹已被訪問,直接輸出該結點
2)右子樹沒被訪問,訪問右子樹。
如何確定右子樹是否被訪問,就需要一個last結點來記錄。


class Postorder {
    ArrayList<Integer> result = new ArrayList<>(); 
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        TreeNode cur = root; 
        TreeNode last = null; 
        Stack<TreeNode> s = new Stack<>(); 
        while ( cur!=null ) {
            s.push(cur);
            cur = cur.left; 
        }
        while ( !s.isEmpty() ) {
            cur = s.pop(); 
            if ( cur.right!=null && last!=cur.right ) {
                s.push(cur); 
                cur = cur.right; 
                while ( cur!=null ) {
                    s.push(cur); 
                    cur = cur.left; 
                }
            } else {
                result.add(cur.val); 
                last = cur; 
            }
        }
        return result; 
    }
} 

中序遍歷 LeetCode 144
同前序遍歷,注意入棧順序即可。


class Inorder {
    ArrayList<Integer> result = new ArrayList<>();
    Stack<TreeNode> s = new Stack<>(); 
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        TreeNode cur = root; 
        while ( cur!=null || !s.isEmpty() ) {
            if ( cur!=null ) {
                 s.push(cur);
                 cur = cur.left;
            } else {
                cur = s.pop(); 
                result.add(cur.val);
                cur = cur.right;
            }
        }
        return result;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章