二叉树的前中后顺遍历(递归、栈)---Java实现

二叉树的前中后顺遍历(递归、栈)Java实现

前序遍历

  • 递归
import java.util.ArrayList;
import java.util.List;

public class PreOrder {

    public List<Integer> preOrder(TreeNode root) {
        List<Integer> res = new ArrayList<>();

        helper(root, res);

        return res;
    }

    public void helper(TreeNode root, List<Integer> res) {
        if (root != null) {
            res.add(root.val);

            if (root.left != null) {
                helper(root.left, res);
            }

            if (root.right != null) {
                helper(root.right, res);
            }

        }
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x;}
}
public List<Integer> stackTravers_preorder(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();

        TreeNode curr = root;
        while (curr != null || !stack.isEmpty()) {
            while (curr != null) {
                res.add(curr.val);
                stack.push(curr);
                curr = curr.left;
            }

            if (!stack.isEmpty()) {
                curr = stack.pop();
                curr = curr.right;

            }
        }

        return res;
    }

中序遍历

  • 递归
import java.util.ArrayList;
import java.util.List;

public class PreOrder {

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        helper(root, res);
        return res;
    }

    // recursive
    public void helper(TreeNode root, List<Integer> res) {
        if (root != null) {
            if (root.left != null) {
                helper(root.left, res);
            }

            res.add(root.val);

            if (root.right != null) {
                helper(root.right, res);
            }

        }
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x;}
}
public List<Integer> stackTraversl(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();

        TreeNode curr = root;
        while (curr != null || !stack.isEmpty()) {

            // push the left tree into stack
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }

    		// when reached leaf node
            curr = stack.pop();
            res.add(curr.val);
            curr = curr.right;
        }

        return res;
    }

后续遍历

  • 递归
import java.util.ArrayList;
import java.util.List;

public class PostOrder {

    public List<Integer> postOrderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        helper(root, res);
        return res;
    }

    // recursive
    public void helper(TreeNode root, List<Integer> res) {
        if (root != null) {
            if (root.left != null) {
                helper(root.left, res);
            }
            if (root.right != null) {
                helper(root.right, res);
            }
            res.add(root.val);
        }
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x;}
}

算法核心思想:
首先要搞清楚先序、中序、后序的非递归算法共同之处:用栈来保存先前走过的路径,以便可以在访问完子树后,可以利用栈中的信息,回退到当前节点的双亲节点,进行下一步操作。
后序遍历的非递归算法是三种顺序中最复杂的,原因在于,后序遍历是先访问左、右子树,再访问根节点,而在非递归算法中,利用栈回退到时,并不知道是从左子树回退到根节点,还是从右子树回退到根节点,如果从左子树回退到根节点,此时就应该去访问右子树,而如果从右子树回退到根节点,此时就应该访问根节点。所以相比前序和后序,必须得在压栈时添加信息,以便在退栈时可以知道是从左子树返回,还是从右子树返回进而决定下一步的操作。
————————————————
版权声明:本文为CSDN博主「coder__666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/coder__666/article/details/80349039

public List<Integer> stackTravers_postorder(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();      // 辅助栈,用于保存,压入栈的是左子树还是右子树

        TreeNode curr = root;
        int left = 1;  // note left tree
        int right = 2; // note right tree

        while (curr != null || !stack.isEmpty()) {

            while (curr != null) {
                stack.push(curr);
                stack2.push(left);
                curr = curr.left;
            }

            while (!stack.isEmpty() && stack2.peek() == right) {
                // 如果是从左子节点返回父节点,则任务完成,将两个栈的栈顶弹出,记录结果
                stack2.pop();
                res.add(stack.pop().val);
            }

            if (!stack.isEmpty() && stack2.peek() == left) {
                // 如果是从左子树返回,则先将辅助栈弹出栈顶,下一个应该压栈的是右子树
                //
                stack2.pop();
                stack2.push(right);
                curr = stack.peek().right;

            }

        }


        return res;
    }

参考链接

CSDN

力扣 中序遍历 题解

猜你喜欢

转载自www.cnblogs.com/tangg/p/13196890.html