JS 二叉树基本操作

二叉树的翻转

    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
};

猜你喜欢

转载自blog.csdn.net/weixin_42207975/article/details/107731900