LeetCode 数、二叉树、二叉搜索树篇(94、144、145)

94. 二叉树的中序遍历

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
1

2
/
3

输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

//中序遍历 必会
//两个思路 递归、栈


//第三种方法 颜色标记法 来及网友Henry
//核心思想,搞一个栈用来存储遍历过的,根据要求遍历的顺序,将可以放入的指为灰色,不能的为白色
//不断弹出栈顶元素进行判断
//本质为自己手动维护一个递归的栈

//第四种方法 莫里斯中序遍历 通过改变树的结构的遍历(不做要求)

solution1 递归

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

solution2 栈

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List <Integer> res = new ArrayList <> ();
        Stack <TreeNode> stack = new Stack<>();
        TreeNode curr = root;
        while (curr != null || !stack.isEmpty()){
            //先把根结点放入stack
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }
            curr = stack.pop();
            res.add(curr.val);
            curr = curr.right;
        }
        return res;
    }
}

solution3 颜色标记法

class Solution {
    class ColorNode{
        TreeNode node;
        String color;
        public ColorNode(TreeNode node,String color){
            this.node = node;
            this.color = color;
        }
    }
    public List<Integer> inorderTraversal(TreeNode root) {
        if (root == null) return new ArrayList<Integer>();
        
        List<Integer> res = new ArrayList<>();
        Stack<ColorNode> st = new Stack<>();
        st.push(new ColorNode(root,"white"));
        while (!st.isEmpty()){
            ColorNode cn = st.pop(); //先把结点pop出来
            if (cn.color == "white"){
                if (cn.node.right != null) st.push(new ColorNode(cn.node.right,"white"));
                st.push(new ColorNode(cn.node,"grey"));
                if (cn.node.left != null) st.push(new ColorNode(cn.node.left,"white"));
            }else {
                res.add(cn.node.val);
            }
        }
        return res;
    }
}

144. 二叉树的前序遍历

给定一个二叉树,返回它的 前序 遍历。

示例:

输入: [1,null,2,3]
1

2
/
3

输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

solution1 递归

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

solution2 用栈进行迭代

//用栈保存根结点,最后一棵树放在最上方
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        TreeNode curr = root;
        while (curr != null || !st.isEmpty()){ //防止一开始为空
            while (curr != null) {
                res.add(curr.val);
                st.push(curr);
                curr = curr.left;
            }
            curr = st.pop().right;
            
        }
        return res;
        
    }
}

solution3 颜色标记法

class Solution {
    class ColorNode{
        TreeNode node;
        String color;
        public ColorNode(TreeNode node,String color){
            this.node = node;
            this.color = color;
        }
    }
    public List<Integer> preorderTraversal(TreeNode root) {
        if (root == null) return new ArrayList<>();
        List<Integer> res = new ArrayList<>();
        Stack<ColorNode> st = new Stack<>();
        st.push(new ColorNode(root,"white"));
        while (!st.isEmpty()){
            ColorNode cn = st.pop();
            if (cn.color == "white"){
                if (cn.node.right != null) st.push(new ColorNode(cn.node.right,"white"));
                if (cn.node.left != null) st.push(new ColorNode(cn.node.left,"white"));
                st.push(new ColorNode(cn.node,"grey"));
            }else {
                res.add(cn.node.val);
            }
        }
        return res;
        
    }
}

145. 二叉树的后序遍历

给定一个二叉树,返回它的 后序 遍历。

示例:

输入: [1,null,2,3]
1

2
/
3

输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

 //三种思路
 //新递归(终结条件+当前层+下探层+(清理本层))
 //迭代 (把左树和根压入栈,再从栈弹出,判断是否有右子树)
 //颜色标记

solution1 递归

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

}

solution2 栈+迭代

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        if (root == null) return new ArrayList<>();
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        TreeNode curr = root;
        TreeNode last = null;//用于遍历右子树时,存储上一个节点
        while(curr!=null || !st.isEmpty()){
            //压根和左子树
            while(curr!=null){
                st.push(curr); 
                curr = curr.left;
            }
            curr = st.peek(); //判断是否有右数
            if(curr.right == null || curr.right == last){ //右边为空,或者已经遍历过了
                res.add(st.pop().val);
                last = curr;//记录
                curr = null;
            }else{
                curr = curr.right;
            }
        }
        return res;
    }
}

solution3 颜色标记法

class Solution {
    class ColorNode{
        TreeNode node;
        String color;
        public ColorNode(TreeNode root,String color){
            this.node = root;
            this.color = color;
        }
    }
    public List<Integer> postorderTraversal(TreeNode root) {
        if (root == null) return new ArrayList<>();
        List<Integer> res = new ArrayList<>();
        Stack<ColorNode> st = new Stack<>();
        st.push(new ColorNode(root,"white"));
        while(!st.isEmpty()){
            ColorNode cn = st.pop();
            if(cn.color == "white"){
                st.push(new ColorNode(cn.node,"grey"));
                if (cn.node.right!= null) st.push(new ColorNode(cn.node.right,"white"));
                if (cn.node.left!= null) st.push(new ColorNode(cn.node.left,"white"));
            }else{
                res.add(cn.node.val);
            }
        }
        return res;
    }
}
posted @ 2020-06-12 22:23  gg12138  阅读(146)  评论(0编辑  收藏  举报