【code基础】树的三种遍历的常规解法

树的中序遍历有三种解法,包括:

  • 递归 (好理解,代码简单,但效率不高)
  • 借助栈的迭代方法
  • 莫里斯遍历

1.递归


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

    //中序
    public List<Integer> inorderTraversal(TreeNode root) {
            //递归的边界条件,返回res即对res不做操作
            if (root == null) return res;
            //保证如下顺序,一定是先遍历,再add
            inorderTraversal(root.left);
            res.add(root.val);
            inorderTraversal(root.right);

            return res;
        }

    //后序
    public List<Integer> postorderTraversal(TreeNode root) {
            //递归的边界条件,返回res即对res不做操作
            if (root == null) return res;
            //保证如下顺序,一定是先遍历,再add
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            res.add(root.val);

            return res;
    }

2.借助于栈做迭代

        //前序--迭代方法-栈保存顺序
        public List<Integer> preorderTraversal2(TreeNode root) {
            if (root == null) return res;

            Stack<TreeNode> st = new Stack<>();
            st.push(root);
            while (!st.isEmpty()){
                TreeNode pop = st.pop();
                res.add(pop.val);
                //后进先出
                if (pop.right!=null) st.push(pop.right);
                if (pop.left!=null) st.push(pop.left);
            }
            return res;
        }

      // 中序--迭代方法-栈保存顺序
      public List<Integer> inorderTraversal(TreeNode root) {
            if (root == null) return res;
            Stack<TreeNode> st = new Stack<>();
            while (root!=null ||!st.isEmpty()){
                //遍历左子树
                while (root !=null){
                    st.push(root);
                    root = root.left;
                }
                //左子树遍历完了,取左子树最左下的结点,加入res
                root= st.pop();
                res.add(root.val);
                //遍历最下结点的右子树
                root = root.right;
            }
            return res;
        }

    // 后序--迭代方法-栈+被访问指针保存顺序
      public List<Integer> postorderTraversal1(TreeNode root) {
            if (root == null) return res;
            TreeNode pre = null; //已遍历过的指针
            Stack<TreeNode> st = new Stack<>();
            while (root!=null ||!st.isEmpty()){
                //遍历左子树
                while (root !=null){
                    st.push(root);
                    root = root.left;
                }
                //左子树遍历完了,取左子树最左下的结点
                root= st.pop();
                //出栈条件: 右结点为空
                if (root.right == null || root.right == pre){
                    res.add(root.val);
                    pre = root;
                    root = null;
                }
                //右子树不空的时候,根结点继续入栈,遍历右结点
                else {
                    st.push(root);
                    root = root.right;
                }
            }
            return res;
        }
posted @ 2022-10-05 14:08  xiaoyu_jane  阅读(40)  评论(0编辑  收藏  举报