二叉树的遍历节点算法题有几种类型:
- 前/中/后序遍历
- 层序遍历
- Z型层序遍历
前/中/后序遍历
首先从前中后序遍历来看,三者的代码基本一致,就是不同顺序代码的顺序也换换。前序是根节点第一个也就是最先遍历,中后同理。一般来说用的是递归,比较简单直接放代码
var preorderTraversal = function(root, res=[]) {
if (!root) return res
res.push(root.val)
preorderTraversal(root.left, res)
preorderTraversal(root.right, res)
return res
};
要注意的点不多,⚠️别忘了最后也要返回一次res。可以换一种更容易懂的写法:
var preorderTraversal = function(root) {
const res=[]
function traversal(root, res) {
if (!root) return res
res.push(root.val)
traversal(root.left, res)
traversal(root.right, res)
return res
}
return traversal(root, res)
};
层序遍历
用的基础好理解的写法,有几个需要注意的点⚠️。
是双层循环,外层是判断整体是否遍历完成,内层是判断这一层是否遍历完成,那么在当前的这一层循环结束后下一层循环开始前,需要做两件事:
1 知道下一层的节点个数用于循环,不能边循环边取,因为stack的长度会越来越小
2 在res中放入一个新的占位数组。然后最后不要忘了return。
同时在第一次判断没有root时记得返回的是一个空数组
var levelOrder = function(root) {
if(!root) {
return []
}
const stack=[]
const res=[]
stack.push(root)
while(stack.length!==0){
let len=stack.length
res.push([])
for(let i=0;i<len;i++){
const node=stack.shift()
res[res.length-1].push(node.val)
if(node.left) stack.push(node.left)
if(node.right) stack.push(node.right)
}
}
return res
};
Z型层序遍历
这个和层序遍历思路一致,但加多一个计数的变量,在偶数行就从右边开始数起,这个数起指的是数据从前面加入到数组中,即用unshift来代替push
var zigzagLevelOrder = function(root) {
if(!root) return []
const stack=[]
const res=[]
let count=0
stack.push(root)
while(stack.length!==0){
const len=stack.length
res.push([])
for(let i=0;i<len;i++){
const node=stack.shift()
if(count%2==0){
res[res.length-1].push(node.val)
}else{
res[res.length-1].unshift(node.val)
}
if(node.left) stack.push(node.left)
if(node.right) stack.push(node.right)
}
count++
}
return res
};