樹的遍歷總結 leetcode

Binary Tree Preorder Traversal

遞歸

複雜度

時間O(n), 空間O(1)node

代碼

public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        traverse(root, result);
        return result;
        
    }
    private void traverse(TreeNode root, ArrayList<Integer> result){
        if (root == null){
            return;
        }
        result.add(root.val);
        traverse(root.left, result);
        traverse(root.right, result);
    }

迭代

複雜度

時間O(n), 空間O(logn) 由於在遍歷過程當中,棧中最多會存儲從root到最深的leave這一條path上的所有node,即樹高O(lgn)post

代碼

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

Binary Tree Preorder Traversal

遞歸

複雜度

時間O(n), 空間O(1)code

代碼

public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        traverse(root, result);
        return result;
        
    }
    private void traverse(TreeNode root, ArrayList<Integer> result){
        if (root == null){
            return;
        }
        result.add(root.val);
        traverse(root.left, result);
        traverse(root.right, result);
    }

Binary Tree Inorder Traversal

迭代

複雜度

時間O(n), 空間O(logn) 由於在遍歷過程當中,棧中最多會存儲從root到最深的leave這一條path上的所有node,即樹高O(lgn)遞歸

代碼

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

遞歸

複雜度

時間O(n), 空間O(1)接口

代碼

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

Binary Tree Postorder Traversal

遞歸

複雜度

時間O(n), 空間O(1)List

代碼

public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<Integer>();
    if (root == null) {
        return res;
    }
    helper(res, root);
    return res;
}
public void helper(List<Integer> res, TreeNode root) {
    if (root == null) {
        return;
    }
    helper(res, root.left);
    helper(res, root.right);
    res.add(root.val);
}

迭代

說明

在出棧的時候須要分狀況一下:
1)若是當前棧頂元素的右結點存在而且還沒訪問過(也就是右結點不等於上一個訪問結點),那麼就把當前結點移到右結點繼續循環;
2)若是棧頂元素右結點是空或者已經訪問過,那麼說明棧頂元素的左右子樹都訪問完畢,應該訪問本身繼續回溯了。搜索

複雜度

時間O(n), 空間O(logn) 由於在遍歷過程當中,棧中最多會存儲從root到最深的leave這一條path上的所有node,即樹高O(lgn)循環

代碼

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }
        TreeNode pre = null;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                stack.push(root);
                root = root.left;
            } else {
                TreeNode peak = stack.peek();
                if (peak.right != null && pre != peak.right) {//若是當前棧頂元素的右結點存在而且還沒訪問過(也就是右結點不等於上一個訪問結點)就訪問右結點 /

                    root = peak.right;
                } else {//若是棧頂元素右結點是空或者已經訪問過,那麼說明棧頂元素的左右子樹都訪問完畢 須要把棧頂元素加入結果而且回溯上一層
                    stack.pop();
                    res.add(peak.val);
                    pre = peak;
                }
                
            }
        }
        return res;
    }

Binary Tree Level Order Traversal I & II

說明

相似樹的廣度優先搜索, 用queue來實現, 使用queue保存每層的節點。出隊和將子節點入隊的實現使用 for 循環,將每一輪的節點輸出。
Queue是接口, LinkedList能夠實現此接口。rsa

複雜度

時間O(n) 空間 O(n)遍歷

代碼

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> res= new ArrayList<List<Integer>>();
    if (root == null) {
        return res;
    }
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.offer(root);
    while (!queue.isEmpty() ) {
        int size = queue.size();
        List<Integer> tem = new ArrayList<Integer>();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            tem.add(node.val);
            if (node.left != null) {
                queue.offer(node.left);
            }
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
        res.add(tem);
        //res.add(0, tem); //for II 
    }
    return res;
}

Binary Tree Zigzag Level Order Traversal

複雜度

時間O(n) 空間 O(n)

代碼

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (root == null) {
            return res;
        }
        boolean flag = true;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            List<Integer> tem = new ArrayList<Integer>();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                if (flag) {
                    tem.add(node.val);
                } else {
                    tem.add(0,node.val);
                }
            }
            flag = !flag;
            res.add(tem);
        }
        return res;
    }
相關文章
相關標籤/搜索