[LeetCode] 問題系列 - Binary Tree Traversal

從大的層面講,Binary Tree 可以用DFS和BFS。

  • 對(duì)于BFS,我們需要 iterative with queue
  • 對(duì)于DFS,Binary Tree 有三種traversal的方式:
    ** Inorder Traversal: left -> root -> right
    ** Preoder Traversal: root -> left -> right
    ** Postoder Traveral: left -> right -> root

記憶方式:order的名字指的是root在什么位置。left,right的相對(duì)位置是固定的。

圖片來源:https://leetcode.com/articles/binary-tree-right-side-view/

對(duì)于時(shí)間復(fù)雜度來說,基本上都是O(n),因?yàn)橐L問所有的點(diǎn)。
對(duì)于空間復(fù)雜度來說,BFS取決于掃描過程中每層的node數(shù),就是樹的寬度,而DFS取決于掃描過程中樹的深度。最壞情況兩個(gè)都是O(n)。

本文重點(diǎn)討論iterative和recursive方法。對(duì)于morris,另開一篇介紹。

Inorder Traversal

首先是recursion寫法,相對(duì)簡(jiǎn)單:

// left->root->right
public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    res.addAll(inorderTraversal(root.left));
    res.add(root.val);
    res.addAll(inorderTraversal(root.left));
}

如果用iteration:

public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.isEmpty()) {
        while (cur != null) { // 把左路徑上遇到的點(diǎn)都放進(jìn)stack里面
            stack.push(cur);
            cur = cur.left;
        } // while循環(huán)結(jié)束的時(shí)候,cur==null
        cur = stack.pop();
        res.add(cur.val);
        cur = cur.right;
    }
    return res;
}

Preorder Traversal

首先是recursion寫法,相對(duì)簡(jiǎn)單:

// root->left->right
public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    res.add(root.val);
    res.addAll(inorderTraversal(root.left));
    res.addAll(inorderTraversal(root.left));
}

如果用iteration:

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

Postorder Traversal

首先是recursion寫法,相對(duì)簡(jiǎn)單:

// left->right->root
public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if (root == null) {
        return res;
    }
    res.addAll(inorderTraversal(root.left));
    res.addAll(inorderTraversal(root.left));
    res.add(root.val);
}

如果用iteration:

public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> res = new LinkedList<>(); // 便于Insert操作
    if (root == null) {
        return res;
    }
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);

    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        res.add(0, node.val); // 因?yàn)檫@一步,所以轉(zhuǎn)變成了root->right->left
        if (node.left != null) {
            stack.push(node.left);
        }
        if (node.right != null) {
            stack.push(node.right);
        }
    }
    return res;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容