【leetcode】二叉树遍历迭代法的统一模板

【leetcode】二叉树遍历迭代法的统一模板


在这里插入图片描述

题目

leetcode上二叉树前中后序遍历对应的题目

144. 二叉树的前序遍历

94. 二叉树的中序遍历

[145. 二叉树的后序遍历](

思路

在这里插入图片描述
前面学习了二叉树三种遍历方式的递归和迭代写法:

【leetcode】144.二叉树的前序遍历

【leetcode】94.二叉树的中序遍历

【leetcode】145.二叉树的后序遍历

但是迭代写法前序和后序相似,而中序则很不同。

在遍历二叉树时,我们先访问的是中间节点,而前序遍历刚好就是要先处理中间节点,访问和处理可以同时进行。后续遍历的代码和前序遍历一样,也是先访问中间节点并处理中间节点,只不过交换左右节点的入栈顺序并且最后翻转一下结果数组。

但是中序遍历要先处理的是左节点,但是访问时先访问的是中间节点,处理和访问不能同时进行。

迭代统一写法

  • 用栈来保存访问过的节点,注意要保证出栈的顺序与遍历顺序一致。比如中序遍历是“左中右”,那么入栈的顺序应该为“右中左”,这样出栈时才是"左中右"。
  • 我们要处理的节点都是中间节点,只不过三种遍历方式处理中间节点的顺序不一样。在中间节点入栈时我们要标记一下,用于判断该节点是中间节点。怎么标记呢?可以在中间节点入栈后再入栈一个空节点null。
  • 首先判断根节点是否为空,不为空就入栈。
  • 开始遍历时,让当前节点指向栈顶节点,分为2种情况:
    • 栈顶节点不为空,那么我们要按顺序将该节点和它的左右节点入栈,这里就是三种遍历方式唯一不同的地方。
    • 栈顶节点为空,说明遇到了可以处理的中间节点,将空节点弹出,然后弹出中间节点,并将它的值加入结果数组。
  • 遍历结束的条件就是栈为空。

代码

在这里插入图片描述

  • 统一模板
var preorderTraversal = function(root) {
    let stack = []
    let ans = []

    if(root) stack.push(root)

    while(stack.length){
        // 当前指针指向栈顶节点
        let cur = stack[stack.length - 1]

        if(cur){    // 当前节点不为空
            stack.pop()
            // TODO:按照各自遍历顺序将节点入栈,入栈中间节点后要入栈一个空节点
            //...
            
            
        }else{  //当前节点为空
            // 弹出空节点
            stack.pop()
            // 弹出中间节点并将它的值加入结果数组
            ans.push(stack.pop().val)
        }
    }

    return ans
};

如以上代码所示,三种遍历方式只有TODO区域的代码有所差异

  • 前序遍历
// TODO:按照各自遍历顺序将节点入栈,入栈中间节点后要入栈一个空节点
if(cur.right) stack.push(cur.right)
if(cur.left) stack.push(cur.left)
stack.push(cur)
stack.push(null)
  • 中序遍历
// TODO:按照各自遍历顺序将节点入栈,入栈中间节点后要入栈一个空节点
if(cur.right) stack.push(cur.right)
stack.push(cur)
stack.push(null)
if(cur.left) stack.push(cur.left)
  • 后续遍历
// TODO:按照各自遍历顺序将节点入栈,入栈中间节点后要入栈一个空节点
stack.push(cur)
stack.push(null)
if(cur.right) stack.push(cur.right)
if(cur.left) stack.push(cur.left)

关注我的专栏,每天更新三道leetcode题解,一起变强!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端corner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值