[路飞]二叉树的后序遍历

115 阅读2分钟

题目描述

image.png

分析

输入:Object,二叉树,每个节点有三个属性(val, left, right)
输出:Array,遍历的结果,把节点的 val,按照顺序放到 Array 里

解题思路

首先解释下什么是后序:前中后说的是当前节点(中)遍历的时候所在的顺序是第几位,

前序:中,前,后
中序:前,中,后
后序:前,后,中

这道题的“进阶”部分告诉我们迭代算法更优,那我们就用递归算法先来一遍 😏

首先要说的是,递归确实就如同题目所言,很简单,我们可以直接去递归地遍历节点,先向左遍历,知道为 null 后,再向右遍历,知道为 null,最后是中间的 node,然后这个过程中,依次地去 push 他们的 val

然后我们看 迭代 的思想,首先两者的区别是:递归就是不停的调用函数,而迭代则用一个 while 循环去代替他。

首先,我们会用一个栈 stack 去保存我们遍历到的节点,然后依次地去弹出节点,获取值,再把值放进一个数组里,最终返回这个数组。

我们具体的执行过程是这样的,首先,我们把 stack 这样赋值 [root],这样是为了我们的执行过程有一个开始的节点,显然就是 root,由于我们会在整个过程中,不断的从栈中取节点,拿 val,放到另一个数组 res,然后再去 push 当前 pop 出来的节点的 leftright,所以我们 while 的就是栈的长度,即只要栈还有长度,我们的整个过程就会一直执行。

至于 push 入栈的顺序和 val 进入 res 的顺序,我们具体再解释下:

首先看后序的要求:前,后,中,也就是 root.left, root.right, root
首先,我们肯定会先遍历到 root,然后才是 root.left & root.right
而取 val 则要先取 root.left
所以我们先可以 unshift root.val, 然后向栈中 push root.left 最后 root.right,这样最终能按照正确的顺序拿到所有的值~

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function (root) {
  // Iteration
  const res = []
  const stack = [root]
  if (!root) return res

  while (stack.length) {
    root = stack.pop()
    res.unshift(root.val)
    if (root.left) stack.push(root.left)
    if (root.right) stack.push(root.right)
  }

  return res
}