二叉树的翻转
function reverseTree(root) {
if (root !== null) {
[root.left, root.right] = [root.right, root.left]
reverseTree(root.left)
reverseTree(root.right)
}
}
判断二叉树是否完全对称
function isSymmetrical(root) {
if (!root) return true
else judge(root.left, root.right)
}
function judge(left, right) {
if (!left) return right === null
if (!right) return false
if (left.val !== right.val) return false
return judge(left.right, right.left) && judge(left.left, right.right)
}
求二叉树的深度
function deep(root) {
if (!root) return 0;
return Math.max(deep(root.left), depp(root.right)) + 1
}
二叉树的前中后序遍历【递归】
区别就是 console.log(root) 的摆放位置,下面为后序遍历。
function func(root) {
if (!root) return
func(root.left)
func(root.right)
console.log(root);
}
二叉树的前中后序遍历【非递归】
下面代码分别为前中后序遍历
var arr=[],res=[];
if(root!=null){
arr.push(root);
}
while(arr.length!=0){
var temp=arr.pop();
res.push(temp.val);
//这里先放右边再放左边是因为取出来的顺序相反
if(temp.right!=null){
arr.push(temp.right);
}
if(temp.left!=null){
arr.push(temp.left);
}
}
return res;
var arr=[],res=[];
while(true){
while(root!=null){
arr.push(root);
root=root.left;
}
//终止条件:最后树遍历完了自然就结束
if(arr.length==0){
break;
}
var temp=arr.pop();
res.push(temp.val);
root=temp.right;
}
return res;
var arr=[],res=[];
arr.push(root);
while(arr.length!=0){
var p=arr.pop();
res.push(p.val);
if(p.left!=null){
arr.push(p.left);
}
if(p.right!=null){
arr.push(p.right);
}
}
return res.reverse();
二叉树层次遍历
先初始化,把root放进stack,并设size为1。
遍历stack,在size范围内获取stack中结点的值,并把其子节点按左到右的顺序存入stack。
当一层遍历完之后重新计算size(此时stack中只有某一层的所有结点),以保证后续新push入结点不会混入它层进行遍历,重复上述步骤。
function levelOrder(root) {
if (!root) return []
let res = []
let stack = [root]
let size = stack.length
let level = []
let curNode
while (stack.length !== 0) {
while (size-- > 0) {
curNode = stack.shift()
level.push(curNode.val)
curNode.left && stack.push(curNode.left)
curNode.right && stack.push(curNode.right)
}
res.push(level)
level = []
size = stack.length
}
return res
}
二叉树的重建
本题是leetcode的剑指offer07题。
题目给出了一个二叉树的前序遍历和中序遍历数组,前序遍历数组第一个值即为二叉树根节点的值。
得到了根节点的值,就可以在中序遍历数组中循环进行比较,当有 inorder[i] === rootVal 时,则该 i 左侧子数组为该二叉树根节点的左子树的中序遍历数组,同理该 i 的右侧子数组为其右子树的中序遍历数组。
注意,这个 i 除了作为遍历中序遍历数组时的计数变量,它也代表根节点左子树结点数量。
最后通过递归完成二叉树的重建。
注:如果题目给的是中序遍历数组以及后序遍历数组,算法思路也类似。
var buildTree = function(preorder, inorder) {
let i
if(!preorder.length || !inorder.length) return null;
const rootVal = preorder[0]
const node = new TreeNode(rootVal)
for(i=0;i<inorder.length;++i){
if(inorder[i] === rootVal) break;
}
// i有两个含义,一个是根节点在中序遍历结果中的下标,另一个是当前左子树的节点个数
node.left = buildTree(preorder.slice(1,i+1),inorder.slice(0,i))
node.right = buildTree(preorder.slice(i+1),inorder.slice(i+1))
return node
};