【数据结构与算法 | 二叉树篇】二叉树的前中后序遍历(迭代版本)

1. 前言

前文我们实现了二叉树前中后三种遍历方式的递归版本,非常简单. 接下来我们来实现一下其迭代版本.

2. 二叉树的前序遍历

(1). 题

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

 

4f4241238c5f6f39b2eefa04fb8bf95b.jpeg

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

 

cfa471a10c82191fbb16c9d457db515c.jpeg

输入:root = [1,2]
输出:[1,2]

示例 5:

 

80c0a844be1cefc61cd7412c67c5eb8d.jpeg

输入:root = [1,null,2]
输出:[1,2]

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

(2). 思路

递归调用系统栈,迭代算法自己构造一个栈来模拟. cur指针指向根节点,while循环,条件只要cur不为空并且栈不为空,不断将元素添加到数组中(根),直到访问到最左的叶子节点(左). 此时将其从栈弹出,访问右节点(右). 如果该右节点为空,则继续弹栈,访问弹栈出的节点右节点.不断继续此过程.

(3). 解

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Deque<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root;
        TreeNode p;
        while (cur != null || !stack.isEmpty()){
            if (cur != null) {
                stack.push(cur);
                list.add(cur.val);
                cur = cur.left;
            } else {
                p = stack.pop();
                cur = p.right;
            }
        }
        return list;
    }
}

3. 二叉树的中序遍历

(1). 题

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例 1:

 

3b2da8f54d47998c00453fdad70b070d.jpeg

输入:root = [1,null,2,3]
输出:[1,3,2]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

(2). 思路

while循环开始,如果cur不为null则一直压栈(左),直到cur为null,弹栈,并访问该节点(根),继续讨论该节点的右孩子(右). 继续弹栈,该节点的左孩子部分已经完成,访问该节点的值,继续讨论其右孩子.直到循环结束.

(3). 解

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Deque<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root;
        TreeNode p;
        while (cur != null || !stack.isEmpty()){
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                p = stack.pop();
                list.add(p.val);
                cur = p.right;
            }
        }
        return list;
    }
}

4. 二叉树的后序遍历

(1). 题

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

示例 1:

 

7946c3dde8d9e906f146604880196ac6.jpeg

输入:root = [1,null,2,3]
输出:[3,2,1]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点的数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

(2). 思路

思路如下.

(3). 解

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> al = new ArrayList<>();
        if (root == null) {
            return al;
        }
        TreeNode cur = root;
        TreeNode pop = null;
        Deque<TreeNode> stack = new LinkedList<>();
        while (cur != null || !stack.isEmpty()){
            //只要cur不为null, 一直访问左节点, 并不断入栈
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                //此时栈顶元素的左孩子为null 即其左孩子无需处理
                    TreeNode peek = stack.peek();
                    //peek.right == null表明栈顶元素的右孩子无需处理
                    //peek.right == pop表明栈顶元素的右孩子已经处理完毕
                    if (peek.right == null || peek.right == pop){
                        //访问该栈顶元素, 并弹出
                        al.add(peek.val);
                        //记录处理的节点
                        pop = stack.pop();
                    } else {
                        //else表明该栈顶元素的右孩子待处理, 则cur = peek.right
                        cur = peek.right;
                    }
                }
        }
        return al;
    }
}

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 01:46:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 01:46:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 01:46:04       82 阅读
  4. Python语言-面向对象

    2024-06-07 01:46:04       91 阅读

热门阅读

  1. python opencv运行报错

    2024-06-07 01:46:04       32 阅读
  2. python pytorch之torch.flip 按轴翻转/倒叙排列 方法

    2024-06-07 01:46:04       27 阅读
  3. mysql like 查询优化

    2024-06-07 01:46:04       25 阅读
  4. c++ 函数作为参数

    2024-06-07 01:46:04       31 阅读
  5. MTK 平台增加分区流程 及 注意事项

    2024-06-07 01:46:04       26 阅读
  6. 高通Android 12/Android 13截屏

    2024-06-07 01:46:04       31 阅读
  7. vue3中函数必须有返回值么?

    2024-06-07 01:46:04       31 阅读