0
点赞
收藏
分享

微信扫一扫

二叉树遍历--非递归

进击的铁雾 2022-04-13 阅读 71
leetcode

二叉树的递归遍历比较简单,但是在遍历节点较多的二叉树时有可能会栈溢出,所以还是非递归更安全

递归的本质还是栈,用栈模仿递归的过程即可

前序遍历

对于每个节点来说,先遍历节点值,再遍历左子树,最后遍历右子树

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode node = root;
        while (!stack.isEmpty() || node != null) {
            if (node != null) {
                // 优先放入节点值
                ans.add(node.val);
                // 放入当前节点,类似存下递归的上层
                stack.push(node);
                // 优先遍历左子树
                node = node.left;
            }
            // 左子树为空,返回上层递归
            node = stack.pop();
            // 遍历右子树
            node = node.right;
        }
        return ans;
    }

中序遍历

左子树 -> 本节点值 -> 右子树

public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode node = root;
        while (!stack.isEmpty() || node != null) {
            while (node != null) {
                // 放入当前节点,类似存下递归的上层
                stack.push(node);
                // 优先遍历左子树
                node = node.left;
            }
            // 左子树为空时,返回上层递归,放入上层节点值
            node = stack.pop();
            ans.add(node.val);
            // 遍历右子树
            node = node.right;
        }
        return ans;
    }

后序遍历

左子树 -> 右子树 -> 本节点值

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode node = root;
        TreeNode prev = null;   // 最近一次访问的节点
        while (!stack.isEmpty() || node != null) {
            while (node != null) {
                // 放入当前节点,类似存下递归的上层
                stack.push(node);
                // 优先遍历左子树
                node = node.left;
            }
            // 返回上层递归
            node = stack.pop();
            // 如果右子树不为空且不是上次访问过的位置
            if (node.right != null && node.right != prev) {
                // 放入当前节点,类似存下递归的上层
                stack.push(node);
                // 遍历右子树
                node = node.right;
            } else {
                // 存下最近一次访问的节点
                prev = node;
                // 存下当前节点值
                ans.add(node.val);
                // 置空,防止重复进入左子树
                node = null;
            }
        }
        return ans;
    }
举报

相关推荐

0 条评论