统一定义树的存储结构:
function TreeNode(val) {
this.val = val;
this.left = null;
this.right = null;
}
二叉树的前序遍历
特点:先访问根节点,然后访问左子节点,最后访问右子节点
递归实现
var preorderTraversal = function(root) {
var res = [];
if(!root) return [];
res.push(root.val);
res = res.concat(preorderTraversal(root.left));
res = res.concat(preorderTraversal(root.right));
return res;
}
迭代实现
var preorderTraversal = function(root) {
var res = [];
var stack = [];
var p = root;
while(p || stack.length > 0) {
while(p) {
res.push(p.val);
stack.push(p);
p = p.left;
}
p = stack.pop().right;
}
return res;
}
var preorderTraversal = function(root) {
if(!root) return [];
var res = [];
let stack = [root];
while(stack.length > 0) {
let node = stack.pop();
res.push(node.val);
if(node.right !== null) {
stack.push(node.right);
}
if(node.left !== null) {
stack.push(node.left);
}
}
return res;
}
中序遍历
特点:先访问左子节点,然后访问根节点,最后访问右子节点
递归实现
var inorderTraversal = function(root) {
if(!root) return [];
let res = [];
res = res.concat(inorderTraversal(root.left));
res.push(root.val);
res = res.concat(inorderTraversal(root.right));
return res;
}
迭代实现
var inorderTraversal = function(root) {
let res = [];
let stack = [];
let p = root;
while(p !== null || stack.length > 0) {
while(p !== null) {
stack.push(p);
p = p.left;
}
p = stack.pop();
res.push(p.val);
p = p.right;
}
return res;
}
后序遍历
特点:先访问左子节点,然后访问右子节点,最后访问根节点
递归实现
var postorderTraversal = function(root) {
if(!root) return [];
let res = [];
res = res.concat(postorderTraversal(root.left));
res = res.concat(postorderTraversal(root.right));
res.push(root.val);
return res;
}
迭代实现
var postorderTraversal = function(root) {
let res = [];
let stack = [];
let set = new Set();
let p = root;
while(p !== null || stack.length > 0) {
while(p !== null && !set.has(p)) {
stack.push(p);
p = p.left;
}
p = stack[stack.length-1];
if(p.right === null || set.has(p)) {
res.push(p.val);
set.add(p);
stack.pop();
if(stack.length === 0) {
return res;
}
p = stack[stack.length-1];
p = p.right;
} else {
set.add(p);
p = p.right;
}
}
return res;
}