145. 二叉树的后序遍历
145. 二叉树的后序遍历
递归
function postorderTraversal(root: TreeNode | null): number[] {
if (!root) {
return []
}
const left = postorderTraversal(root.left)
const right = postorderTraversal(root.right)
return [...left, ...right, root.val]
}
迭代
function postorderTraversal(root: TreeNode | null): number[] {
if (!root) {
return []
}
const result = []
const stack = []
let currentRoot = root
let prevRoot = null
while (currentRoot || stack.length) {
// 处理左结点
while (currentRoot) {
// 处理左结点前先将当前 root 结点入栈
stack.push(currentRoot)
currentRoot = currentRoot.left
}
// 从左结点回到了 root 结点
// 需要从栈取出来,才知道现在是哪个 root 结点
currentRoot = stack.pop()
// 因为是后序遍历,所以要先处理右结点
// 处理右结点
// 什么时候右结点处理完呢?
// 1. 假如没有右结点,那么就已经完了
// 2. 存在的话就去遍历右结点,直到从右结点返回
// 2.1 右结点存在,直接遍历
// 2.2 存在的话还有一个可能是已经处理过了返回回来的
// 所以添加 prevRoot 来标记上次处理的是哪个 root
// 1. 右结点不存在先处理从右结点返回的场景
// 2. 右结点等于上一个处理的结点,说明是从右结点返回的
if (!currentRoot.right || currentRoot.right === prevRoot) {
// 右结点处理完了,往 result push 结果
result.push(currentRoot.val)
// 将 currentRoot 记录为 prevRoot
prevRoot = currentRoot
currentRoot = null
} else {
// 3. 否则存在右结点,并且还没有处理
// 需要再把 root push 回去
// 因为现在还不到处理的时候
stack.push(currentRoot)
// 处理右子树
currentRoot = currentRoot.right
}
}
return result
}