zoukankan      html  css  js  c++  java
  • 【总结】二叉树的前中后序遍历(递归和非递归)

    一、前中后序递归

    1. 前序递归( 时间复杂度O(n)、空间复杂度O(n) )

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

    2. 中序递归( 时间复杂度O(n)、空间复杂度O(n) )

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

    3. 后序递归( 时间复杂度O(n)、空间复杂度O(n) )

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

    二、前中后序非递归

      前中后序遍历都属于深度遍历,所以需要使用栈。层次遍历需要用到队列。

    1. 前序非递归( 时间复杂度O(n)、空间复杂度O(n) )

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

      非递归前序遍历的另一种写法:

    class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            if (root == null) return res;
            Stack<TreeNode> stack = new Stack<>();
            stack.push(root);
            while (!stack.isEmpty()) {
                TreeNode cur = stack.pop();
                res.add(cur.val);
                if (cur.right != null) stack.push(cur.right); // 先加入右子树
                if (cur.left != null) stack.push(cur.left);
            }
            return res;
        }
    }

    2. 中序非递归( 时间复杂度O(n)、空间复杂度O(n) )

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

    3.后序非递归( 时间复杂度O(n)、空间复杂度O(n) )

    class Solution {
        public List<Integer> postorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            TreeNode pre = null; //pre节点用于记录前一次访问的节点
            while (!stack.isEmpty() || root != null) {
                while (root != null) {
                    stack.push(root);
                    root = root.left;
                }
                root = stack.peek();
                // 若右节点为空 或右节点访问过
                if (root.right == null || root.right == pre) {
                    res.add(root.val); //此时可以访问根结点啦
                    stack.pop();
                    pre = root;
                    root = null; //此时下一轮循环不要将左子树压栈,直接判断栈顶元素
                }else {
                    root = root.right; //先不出栈 把它右节点入栈
                }
            }
            return res;
        }
    }

    后序非递归的另一种写法,修改前序【根左右】的遍历顺序为【根右左】,前序遍历是往后加元素,后序遍历是往前加元素

    class Solution {
        //修改前序遍历,每次先查看右节点再查看左节点。同时,节点写入结果将插入队尾修改为插入队首
        public List<Integer> postorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            while (!stack.isEmpty() || root != null) {
                while (root != null) {
                    res.add(0,root.val);  // 取根节点的值,插入list最后边
                    stack.push(root);
                    root = root.right; // 遍历右子树
                }
                root = stack.pop();
                root = root.left; // 遍历左子树
            }
            return res;
        }
    }

    三、层序遍历

    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<>(); // 层序需要借助队列
            queue.offer(root);
            while (!queue.isEmpty()) {
                int level = queue.size();
                List<Integer> list = new ArrayList<>();
                for (int i = 0; i < level; i++) {
                    TreeNode 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;
        }
    }

    四、相关习题

    LeetCode144. 二叉树的前序遍历LeetCode94. 二叉树的中序遍历LeetCode145. 二叉树的后序遍历LeetCode102. 二叉树的层序遍历

    参考:

      二叉树层序遍历问题总结

      二叉树 前序+中序+后序+层序遍历(递归+迭代)

  • 相关阅读:
    Centos7安装部署openstack--Keystone认证服务
    Centos7安装部署openstack----基础服务安装
    Centos7 k8s dns
    集中式存储3apr
    Centos7 k8s部署dahsboard
    Centos7 k8s tomcat-app项目持久化
    Centos7 k8s 容器的网络访问service
    Centos 7 k8s Deployment新副本控制器
    模型层中模型的基本了解
    程序员必知必会Git的小知识
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/12837408.html
Copyright © 2011-2022 走看看