⽤递归的遍历⽅式没啥好说的,说下⽤while循环+stack实现的遍历吧
let bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
},
};
(注意这⾥只有前序遍历才能使⽤队列, 其他都只能使⽤栈来实现, 栈是可以模拟js执⾏栈)
前序遍历:先打印根节点, 在遍历左⼦树, 最后遍历右⼦树
1->2->4->5->3->6->7
中序遍历: 先遍历左⼦树在打印根节点, 最后遍历右⼦树
4->2->5->1->6->3->7
后序遍历: 先遍历左⼦树在遍历右⼦树, 最后打印根点
4->5->2->6->7->3>1
前序遍历 本质上来讲, 其实递归也就是把函数⼀直⼊栈, 出栈操作, 所以完全可以使⽤栈来模拟递归
//栈+while循环实现版本
function frontOrder(tree) {
let stack = [tree];
console.log(stack);
while (stack.length) {
let node = stack.pop();
if (node) {
console.log(node.val);
stack.push(node.right);
stack.push(node.left);
}
}
}
// 递归版
function frontOrder(tree) {
if (!tree) return;
console.log(tree.val);
frontOrder(tree.left);
frontOrder(tree.right);
}
中序遍历
这个相对于前序遍历⽐较复杂,但是还是使⽤stack来实现,另外还多了⼀个指针,⽤来指向当前push的内容
//while循环
function inOrder(tree) {
let stack = []
let p = tree // 先遍历左节点
while (p || stack.length) {
while (p) {
stack.push(p)
p = p.left // 推进左节点
}
let node = stack.pop()
console.log(node.val)
p = node.right
}
}
inOrder(bt)
//递归版
function inOrder(tree) {
if (!tree) return;
inOrder(tree.left);
console.log(tree.val);
inOrder(tree.right);
}
后续遍历
function postOrder(tree) {
if (!tree) return;
postOrder(tree.left);
postOrder(tree.right);
console.log(tree.val);
}
//⾮递归版
// 这⼀块⽐较困难, ⽤两个栈来实现, 第⼀次stack先存储类似于先序遍历的⽅法
function postOrderr(tree) {
let outputStack = []
let stack = [tree]
while (stack.length) {
let n = stack.pop()
outputStack.push(n)
if (n.left) stack.push(n.left)
if (n.right) stack.push(n.right)
}
while (outputStack.length) {
let n = outputStack.pop()
console.log(n.val)
}
}