leetcode 144 145 94 二叉树 前中后序遍历 递归迭代

100 阅读2分钟

对于数的遍历非常符合人类思维,层层递进,无论是递归的每次处理还是迭代的每次循环都是只需关注当前节点极其左右孩子即可。

  1. 递归写法最容易理解,都是在叶子节点作为出口,常规处理只需根据不同遍历方式改变调用顺序就可以。

迭代的分为根据遍历方式容易理解的而写的和改进成统一的迭代遍历写法

  1. 常规迭代前序和后序是大致一样的,都是将递归函数的处理作为每次循环的处理,只需要加入栈结构的应用,利用栈的特殊性质和递归的特点相似的点就可以完成前序遍历,后序遍历则需要利用栈先进后出的特点反向入栈就可以达到一个与后序遍历完全相反的出栈顺序,最后再将出栈顺序的数组列表翻转即可达到后序遍历的顺序。而中序遍历则不同,没有办法单纯通过栈达到满意的顺序,因此需要利用指针只要有左孩子就需要将当前节点和左孩子入栈,只有当没有左孩子时才能做出栈操作并让右孩子入栈。
  2. 改进的统一迭代的写法则需要标记法。利用null这个特殊节点作为标记,因为它除了作为标记的情况,也能同时满足作为叶子节点时的情况。每次入栈操作都以是否为null作为判断,如果为null则删掉顶部节点按照遍历需求决定入栈顺序,需要注意,当前节点入栈后要紧跟其后将null入栈作为标记。若不为null则先先将null弹出再出栈加入结果数组列表。
  • leetcode 144 二叉树前序遍历 easy

题目链接: leetcode.com/problems/bi…

递归:

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

迭代:

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

迭代统一写法:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> tree = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        if (root != null) {
            st.push(root);
        }
        while (!st.isEmpty()) {
            TreeNode cur = st.peek();
            if (cur != null) {
                st.pop();
                if (cur.right != null) {
                    st.push(cur.right);
                }
                if (cur.left != null) {
                    st.push(cur.left);
                }
                st.push(cur);
                st.push(null);
            } else {
                st.pop();
                cur = st.pop();
                tree.add(cur.val);
            }
        }
        return tree;
    }
}
  • leetcode 145 二叉树后序遍历 easy

题目链接: leetcode.com/problems/bi…

递归:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> tree = new ArrayList<>();
        if (root == null) {
            return tree;
        }
        Stack<TreeNode> stackList = new Stack<>();
        stackList.push(root);
        while (!stackList.isEmpty()) {
            TreeNode cur = stackList.pop();
            tree.add(cur.val);
            if (cur.left != null) {
                stackList.push(cur.left);
            }
            if (cur.right != null) {
                stackList.push(cur.right);
            }
        }
        Collections.reverse(tree);
        return tree;
    }
}

迭代:

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

迭代统一写法:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> tree = new ArrayList<>();
        Stack<TreeNode> st = new Stack<>();
        if (root != null) {
            st.push(root);
        }
        while (!st.isEmpty()) {
            TreeNode cur = st.peek();
            if (cur != null) {
                st.pop();
                st.push(cur);
                st.push(null);
                if (cur.right != null) {
                    st.push(cur.right);
                }
                if (cur.left != null) {
                    st.push(cur.left);
                }
            } else {
                st.pop();
                cur = st.peek();
                st.pop();
                tree.add(cur.val);
            }
        }
        return tree;
    }
}
  • leetcode 94 二叉树中序遍历 easy

题目链接: leetcode.com/problems/bi…

递归:

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

迭代:

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

迭代统一写法:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> tree = new ArrayList<>();
    Stack<TreeNode> st = new Stack<>();
    if (root != null) {
        st.push(root);
    }
    while (!st.isEmpty()) {
        TreeNode cur = st.peek();
        if (cur != null) {
            st.pop();
            if (cur.right != null) {
                cur = cur.right;
            }
            st.push(cur);
            st.push(null);
            if (cur.left != null) {
                cur = cur.left;
            }
        } else {
            st.pop();
            cur = st.peek();
            st.pop();
            tree.add(cur.val);
        }
    }
    return tree;
    }
}