二叉树前中后序遍历的递归和非递归实现

目录

  • 二叉树遍历
  • 前序遍历
    • 递归
    • 非递归
  • 中序遍历
    • 递归
    • 非递归
  • 后序遍历
    • 递归
    • 非递归

二叉树遍历

二叉树的遍历分为深度优先和广度优先
深度优先又分为前序遍历、中序遍历和后序遍历
详见:初识二叉树

我们可以理解为对结点的处理顺序在前、中间还是最后
例如:
二叉树前中后序遍历的递归和非递归实现_第1张图片

前序遍历

二叉树的前序遍历
二叉树前中后序遍历的递归和非递归实现_第2张图片

递归

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
           if(root == null){
            return list;
        }
        list.add(root.val);
        List<Integer> left = preorderTraversal(root.left);
        List<Integer> right =preorderTraversal(root.right);
        list.addAll(left);
        list.addAll(right);
        return list;
    }

非递归

思路:
我们提前准备一个栈,保存所经过的路径,然后从根节点一直向左出发,当左孩子为空,然后找右孩子,然后回溯,直到找完。

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null) {
            return list;
        }
        TreeNode cur = root;
        Stack<TreeNode> stack = new Stack<>();

        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                list.add(cur.val);
                cur = cur.left;
            }
            TreeNode pop = stack.pop();
            cur = pop.right;
        }
        return list;
    }
}

中序遍历

二叉树的中序遍历
二叉树前中后序遍历的递归和非递归实现_第3张图片

递归

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

        return list;
    }

非递归

思路:
我们提前准备一个栈,保存所经过的路径,然后从根节点一直向左出发,当左孩子为空,然后找右孩子,然后回溯,直到找完。

        public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }

        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode node = stack.pop();
            list.add(node.val);
            cur = node.right;
        }
        return list;
    }

后序遍历

二叉树的后序遍历
二叉树前中后序遍历的递归和非递归实现_第4张图片

递归

public List<Integer> postorderTraversal1(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }

        List<Integer> left = postorderTraversal(root.left);
        list.addAll(left);
        List<Integer> right = postorderTraversal(root.right);
        list.addAll(right);
        list.add(root.val);

        return list;
    }

非递归

思路:
相比之下,后序遍历的非递归比前两个要麻烦一点,因为不是简单的删除栈顶元素,如果处理不好会造成死循环,所以我们需要判断右孩子是否为空,和是否刚走过右孩子。

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }

        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode last = null;

        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }

            TreeNode node = stack.peek();

            if (node.right == null || node.right == last) {
                // 看作第三次经过
                list.add(node.val);
                last = node;
                stack.pop();
            } else {
                // 第二次经过
                cur = node.right;
            }
        }
        return list;
    }

你可能感兴趣的:(Data,Structure,二叉树,数据结构,前序遍历,中序遍历,后序遍历)