二叉树遍历无非就是递归和迭代
递归有三种方式:先序、中序、后序,框架如下:
function dfs(root) {
if (!root) return
// 前序
dfs(root.left)
// 中序
dfs(root.right)
// 后序
}
迭代有四种方式:先序、中序、后序、层序,框架如下:
// 层序
function bfs(root) {
let queue = root ? [root] : []
for (let cur = null, len = queue.length; len; len = queue.length) {
// 当前层有len个节点
while(len--){
cur = queue.shift() // 访问当前层的节点
// 下层节点即子节点进队列
cur.left && queue.push(cur.left)
cur.right && queue.push(cur.right)
}
}
}
// 先序迭代
function dfs(root) {
let stk = root ? [root] : []
for (let cur = null; stk.length;) {
cur = stk.pop() // 先序访问当前元素
// 先压右后压左
cur.right && stk.push(cur.right)
cur.left && stk.push(cur.left)
}
}
// 后序迭代(根右左倒过来就行,故借用先序思路稍微调整一下就可以实现)
function dfs(root) {
let stk = root ? [root] : []
let stk2 = []
for (let cur = null; stk.length;) {
cur = stk.pop()
stk2.push(cur) // 先收集起来
// 先压左后压右
cur.left && stk.push(cur.left)
cur.right && stk.push(cur.right)
}
for (let cur = null; stk2.length;) cur = stk2.pop() // 后序访问当前元素
}
// 中序迭代
function dfs(root) {
let stk = []
let cur = root // 当前节点指针
while (cur || stk.length) {
if (cur) { // 往死里左压栈
stk.push(cur)
cur = cur.left
} else {
cur = stk.pop() // 中序访问当前元素
cur = cur.right // 右压栈
}
}
}