前序遍历
先根结点,前序遍历左子树,前序遍历右子树
递归实现前序遍历
const preOrderVisit = function (root){
if (!root) return;
console.log(root.val);
preOrderVisit(root.left);
preOrderVisit(root.right);
}
迭代+栈实现前序遍历
const preOrderVisit = function(root){
let stack = [];
stack.push(root);
while (stack.length){
let curNode = stack.pop();
console.log(curNode.val);
if (curNode.right){ // 注意是先压入右子树,先进后出
stack.push(curNode.right);
}
if (curNode.left){
stack.push(curNode.left);
}
}
}
中序遍历
中序遍历左子树,根结点,中序遍历右子树
递归实现中序遍历
const inOrderVisit = function(root){
if (!root) return;
inOrderVisit(root.left);
console.log(root.val);
inOrderVisit(root.right);
}
迭代+栈实现中序遍历
const inOrderVisit = function (root){
let stack = [];
while (root || stack.length){
if (root){
stack.push(root);
root = root.left;
}else{
let tmpNode = stack.pop();
console.log(tmpNode.val);
root = tmpNode.right;
}
}
}
后序遍历
后序遍历左子树,后序遍历右子树,访问根结点
递归实现后序遍历
const postOrderVisit = function (root){
if (!root) return;
postOrderVisit(root.left);
postOrderVisit(root.right);
console.log(root.val);
}
迭代+栈实现后序遍历
const postOrderVisit = function (root) {
// 节点输出的条件:
// 1. node.left == null && node.right == null 输出
// 2. node存在孩子,但node的所有孩子都被访问过了,所以可以输出
let stack = [];
stack.push(root);
let pre = null; // 记录前一个节点
while (stack.length) {
let curNode = stack[stack.length - 1];
if ((!curNode.left && !curNode.right) ||
(!pre && (pre == curNode.left || pre == curNode.right))) {
console.log(curNode.val);
pre = curNode;
stack.pop();
} else {
if (curNode.right) {
stack.push(curNode.right);
}
if (curNode.left) {
stack.push(curNode.left);
}
}
}
}