数据结构之树(其一)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */

 

二叉树的前序遍历 题目 解析

迭代用栈,因为左节点优先,所以先把右节点放入栈再放左节点,左节点出栈。

class Solution {
    private List<Integer> ans = new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        preorder(root);
        return ans;
    }
    public void preorder(TreeNode root) {
        if (root == null) return;
        ans.add(root.val);
        preorder(root.left);
        preorder(root.right);
    }
}
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        if (root == null) return ans;
        LinkedList<TreeNode> st = new LinkedList<>();
        st.addLast(root);
        while(!st.isEmpty()) {
            TreeNode temp = st.removeLast();
            ans.add(temp.val);
            if (temp.right != null) st.addLast(temp.right);
            if (temp.left != null) st.addLast(temp.left);
        }
        return ans;
    }
}

统一模板(建议使用)  仿递归  解析

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        LinkedList<TreeNode> st = new LinkedList<>();
        TreeNode temp = root;
        while(temp != null || !st.isEmpty()) {
            while (temp != null) {
                st.addLast(temp);
                ans.add(temp.val);
                temp = temp.left;
            } 
            temp = st.removeLast();
            temp = temp.right;
        }
        return ans;
    }
}

 

中序遍历 题目 解析

写中序遍历的时候已经忘了前序遍历的迭代怎么写了。

递归和上面一个模板,不写了。迭代也是仿递归的统一模板,先不断把左子节点放入栈直到空节点。然后出栈左节点,把右节点放进去。

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        LinkedList<TreeNode> st = new LinkedList<>();
        TreeNode temp = root;
        while (!st.isEmpty() || temp != null) {
            while(temp != null) {
                st.addLast(temp);
                temp = temp.left;
            }
            temp = st.removeLast();
            ans.add(temp.val);
            temp = temp.right;
        }
        return ans;
    }
}

 

后序遍历 题目 解析

先序遍历根右左,反转为左右根。

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        if (root == null) return ans;
        LinkedList<TreeNode> st = new LinkedList<>();
        st.addLast(root);
        while(!st.isEmpty()) {
            TreeNode temp = st.removeLast();
            ans.add(temp.val);
            if (temp.left != null) st.addLast(temp.left);
            if (temp.right != null) st.addLast(temp.right);
        }
        Collections.reverse(ans);
        return ans;
    }
}

统一模板(建议使用)

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        LinkedList<TreeNode> st = new LinkedList<>();
        TreeNode temp = root;
        while (temp != null || !st.isEmpty()) {
            while (temp != null) {
                st.addLast(temp);
                ans.add(temp.val);
                temp = temp.right;
            }
            temp = st.removeLast();
            temp = temp.left;
        }
        Collections.reverse(ans);
        return ans;
    }
}

 

层序遍历 题目 解析

用队列很容易解决,更多层序遍历的题戳解析。

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        if (root == null) return ans;
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty()) {
            List<Integer> ansone = new ArrayList<>();
            int len = q.size();
            for (int i = 0; i < len; i++) {
                TreeNode temp = q.poll();
                ansone.add(temp.val);
                if (temp.left != null) q.offer(temp.left);
                if (temp.right != null) q.offer(temp.right);
            }
            ans.add(ansone);
        }
        return ans;
    }
}

 递归,记录深度 参考

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        levelOrderHelp(0, root);
        return res;
    }
    private void levelOrderHelp(int deep, TreeNode node) {
        if (node == null) return;
        if (deep == res.size()) {
            res.add(new ArrayList<Integer>());
        } 
        res.get(deep).add(node.val);
        levelOrderHelp(deep + 1, node.left);
        levelOrderHelp(deep + 1, node.right);
    }
}

 

翻转二叉树 题目 解析

其实就是在遍历时加上一步交换子节点的操作,前序,后续,层序都可以。但是中序不行,因为中序的话是交换左子节点,再交换自己,再交换右子节点,但是这样就是左子节点被交换了两次。

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return root;
        TreeNode temp = root.right;
        root.right = root.left;
        root.left = temp;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

 

posted @ 2020-11-06 19:16  CPJ31415  阅读(65)  评论(0)    收藏  举报