Tree Tranverse: Pre/In/Post/Level Order tranverse

Preorder:
迭代写法:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null) return res; //we need to check it is null or not
        
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur = stack.pop();
            res.add(cur.val); 
            if(cur.right != null) stack.push(cur.right); //先push右边的子节点 这样以后Pop出来就是左边的先pop,但是如果之后有变形题目,说逆序的preorder 直接把push的顺序调换过来即可
            if(cur.left != null) stack.push(cur.left);
        }
        return res;
    }
    
}

递归写法:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null) return res;
        helper(root, res);
        return res;
    }
    
    public void helper(TreeNode root, List<Integer> res){
        if(root == null) return;
//先add再递归
        res.add(root.val);
        helper(root.left, res);
        helper(root.right, res);
    }
}

Inorder tranverse:
迭代写法:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null) return res;
        
        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root; //cur指针
        
        while(cur != null || !stack.isEmpty()){
            while(cur != null){ //每一次都是尽可能往左边走 直到走不动
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            res.add(cur.val);
            cur = cur.right;
        }
        return res;
    }
    
}

递归写法:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        
        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);
        
    }
}

postorder tranverse:跟前序遍历比较像
迭代写法:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        
        List<Integer> res = new ArrayList<>();
        if(root == null) return res;
        
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur = stack.pop();
            res.add(0, cur.val);
            if(cur.left != null) stack.push(cur.left); //先Push left这样每次pop出来的就是右边的
            if(cur.right != null) stack.push(cur.right);
        }
        return res;
    }
    
}

递归写法:

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

level order:
迭代写法:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if(root == null) return res;
        
        Queue<TreeNode> queue = new LinkedList<>();
        TreeNode cur = root; //跟中序遍历一样 需要指针
        queue.offer(cur); //但是要先把root给放进queue里面
        while(queue.size() != 0){
            List<Integer> list = new ArrayList<>();
            int size = queue.size();
            for(int i = 0; i<size; i++){//这个for语句的作用只是为了好截取list 然后add到res中 实际上的层次遍历本质上和前序遍历一样
                cur = queue.poll();
                list.add(cur.val);
                if(cur.left != null) queue.offer(cur.left);
                if(cur.right != null) queue.offer(cur.right);
            }
            res.add(list);
        }
        return res;
    }
    
    
}

递归写法:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if(root == null) return res;
        helper(res, root, 0);
        return res;
    }
    
    public void helper(List<List<Integer>> res, TreeNode root, int level) {
        if(root == null) return;
        
        if(res.size() <= level){ //如果需要开辟新的写入层 就直接开辟
            res.add(new ArrayList<>());
        }
        
        //跟前序遍历有点像 先add再双递归
        res.get(level).add(root.val);
    
        helper(res, root.left, level + 1);
        helper(res, root.right, level + 1);
    }
}

总结:
preorder, inorder, postorder are based on DFS
level order are based on BFS.

the iterate way to tranverse:
because pre/in/post are based on DFS, so they use stack(linkedlist)
but level order uses queue(linkedlist)
for inorder and level order tranvese, we needs to use a cur pointer on root
but for pre and post order, we only needs to push the root.
Core statement: while statement:
preorder: while stack is not empty: pop() and added cur.val, stack.pop(cur.right) stack.pop(cur.left)
postorder: while stack is not empty: pop() and added cur.val to the index of 0, stack.push(cur.left) stack.push(cur.right)
inorder: cur = root, while cur not null and stack not empty, while(cur != null){ stack.push(cur); cur = cur.left;}cur = stack.pop(); res.add(cur.val); cur = cur.right; //go all the way left each time until can’t move any further, pop and add it, and move to the right.
levelorder: queue.offer(cur), while (queue.size() != 0) size = queue.size() for () {pull add cur.left, cur.right}\

the recusive way to tranverse:
千种后序遍历都是一样的 只是什么时候添加节点值不一样。
层次遍历和前序遍历比较像 但是需要在递归函数里加一个扩容的操作

posted @ 2020-11-03 01:57  EvanMeetTheWorld  阅读(16)  评论(0)    收藏  举报