我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
给定一个二叉树,返回它的 后序 遍历。
先介绍一下二叉树的遍历规则:
- 二叉树有前序,中序,后序遍历。前、中、后是针对根节点。
- 如前序遍历,根节点就在最前面, 如:
根
左
右
- 如中序遍历,根节点就在中间, 如:
左
根
右
- 如后序遍历,根节点就在最后面, 如:
左
右
根
不难发现,左右子节点的顺序不变,只需要知道根节点的位置就行啦。
解法一:递归思想
// 左 右 中
var postorderTraversal = function(root, res = []) {
if(!root)return res
postorderTraversal(root.left, res)
postorderTraversal(root.right, res)
res.push(root.val)
return res
}
复制代码
解法二:迭代思想
- 首先迭代思想我们需要一个栈来保存遍历过的元素,后序遍历首先
push
的是左子节点。但是我们首先会遍历到根节点,这时,我们需要将遍历的节点推入栈中,然后找它的左子节点,直到没有左子节点。这时候,我们需要从栈里取出一个节点。
const stack = []
let prev = null
while(root || stack.length) { // root存在和stack不为空 循环会一直走下去
while(root){
stack.push(root)
root = root.left // 如果左子节点一直存在,就一直入栈。
}
// 到这里没有左子节点了
root = stack.pop() // 取出栈顶节点
// 右子节点为空时
if(root.right == null || root.right == prev){ // root.right == prev 不会重复遍历右子节点
res.push(root.val) // 左右都为空时 将根节点push进来
prev = root // 保存一下当前的节点
root = null // 这里让我们走外层循环的 stack.length > 0的条件
}else{
// 左边的子节点是优先添加的
res.push(root.val)
root = root.right // 指向右子节点
}
}
复制代码
完整代码
var postorderTraversal = function(root) {
if(!root)return []
const res = []
const stack = []
let prev = null
while(root || stack.length){
while(root){
stack.push(root)
root = root.left
}
root = stack.pop()
if(root.right ==null || root.right == prev){
res.push(root.val)
prev = root
root =null
}else{
stack.push(root)
root = root.right
}
}
return res
}
复制代码