前序遍历
递归
算法递归的方法比较简单,,每次只需要操作当前节点,再先后递归左子节点和右子节点。中序遍历和后序遍历的递归实现,只需要换下3行代码的顺序即可,后面不再给出。
var preorderTraversalNode = function(node, result){
if(node){
result.push(node.val)
preorderTraversalNode(node.left,result)
preorderTraversalNode(node.right,result)
}
}
直接调换顺序即可
使用栈
弹出节点,进行操作,再分别压入其右子节点和左子节点,这样使得下一次弹出的节点会是当前节点的左子节点,满足先序遍历的顺序要求。
var preorderTraversal = function(root) {
//空检测
if(!root) return [];
var result = [];
var stack = [root],
current = null;
while (stack.length !== 0){
current = stack.pop();
result.push(current.val);
current.right && stack.push(current.right);
current.left && stack.push(current.left);
}
return result;
};
中序遍历
中序遍历也是二叉搜索树升序遍历的遍历方法 。
递归
略
使用栈
先将左边压到底,压到底之后开始出栈,进行操作。然后访问该节点的右分支,进行同样操作。
var inorderTraversal = function(root) {
if(!root) return [];
var result = [],
current = root,
stack = [];
while(stack.length !== 0 || current){
while(current){
stack.push(current);
current = current.left;
}
current = stack.pop();
result.push(current.val);
current = current.right;
}
return result;
}
后序遍历
递归
略
使用栈
这里用了一种取巧的方式,后序遍历是左右中的顺序,其反过来就是中右左,也就是反前序遍历,我们只需要修改一下前序遍历访问左右子节点的顺序,即可得到反前序遍历,然后将遍历的结果 reverse ,就得到后序遍历的结果,神奇不神奇!
const postorderTraversal = function(root) {
//空检测
if(!root) return [];
let result = [];
var current = null,
stack = [root];
while(stack.length != 0){
current = stack.pop();
result.push(current.val);
current.left && stack.push(current.left);
current.right && stack.push(current.right);
}
return result.reverse();
};
层序遍历
层序遍历使用队列实现,每一轮都把同一层的节点全部入列,然后在下一轮中依次出列,每个节点进行操作,然后左右子节点分别入列,这样能保证每一层从左往右的顺序。
以 leetcode 637. 二叉树的层平均值 为例给出代码
var averageOfLevels = function(root) {
if(!root) return false;
var que = [root],
current = null,
result = [],
sum = 0;
while(que.length !== 0){
let levLength = que.length;
for(i = 1; i<=levLength; i++){ //这个循环的次数需要固定,因为que.length是变化的
current = que.shift();
sum += current.val;
current.left && que.push(current.left);
current.right && que.push(current.right);
}
result.push(sum/levLength);
sum = 0;
}
return result;
};