02 - 二叉树

24 阅读2分钟

1、二叉树的前中后遍历

function preorderTraversal(root) {
    const res = [];
    dfs(root)
    return res;

    function dfs(root) {
        if (!root) return;
        res.push(root.val);
        dfs(root.left)
        dfs(root.right)
    }
}

2、层序遍历

var levelOrder = function (root) {
    let res = [];
    dfs(root, 0);
    return res;

    function dfs(tree, deep) {
        if (!tree) return;

        // 前序遍历
        if (!res[deep]) res[deep] = [];
        res[deep].push(tree.val);

        dfs(tree.left, deep + 1);
        dfs(tree.right, deep + 1);
    }
};

3、二叉树的最大深度

function maxDepth(root) {
    if (!root) return 0;
    let left = maxDepth(root.left);
    let right = maxDepth(root.right);
    return Math.max(left, right) + 1;
}

4、二叉树中和为某一值的路径(一)

  • 给出如下的二叉树, sum = 22
  • 返回true,因为存在一条路径 5→4→11→2的节点值之和为 22
function hasPathSum(root, sum) {
    if (!root) return false;
    if (!root.left && !root.right && root.val == sum) return true;
    return (
        hasPathSum(root.left, sum - root.val) ||
        hasPathSum(root.right, sum - root.val)
    )
}

5、对称的二叉树

  • 输入一棵二叉搜索树
  • 将该二叉搜索树转换成一个排序的双向链表
function isSymmetrical(pRoot) {
    if (pRoot === null) return true;
    return compare(pRoot.left, pRoot.right)
    function compare(node1, node2) {
        if (node1 === null && node2 === null) return true;
        if (node1 === null || node2 === null) return false;
        if (node1.val !== node2.val) return false;
        return (
            compare(node1.left, node2.right) &&
            compare(node1.right, node2.left)
        )
    }
}

6、合并二叉树

  • 合并规则是:
    • 都存在的结点
    • 就将结点值加起来
    • 否则空的位置就由另一个树的结点来代替
function mergeTrees(t1, t2) {
    if (t1 && t2) {
        t1.val += t2.val
        t1.left = mergeTrees(t1.left, t2.left)
        t1.right = mergeTrees(t1.right, t2.right)
    }
    return t1 || t2
}

7、二叉树的镜像(左右翻转)

function Mirror(root) {
    if (!root) return root;
    [root.left, root.right] = [root.right, root.left];
    Mirror(root.left);
    Mirror(root.right);
    return root;
}

8、判断是不是二叉搜索树

function isValidBST(root) {
    let res = [];
    dfs(root);
    function dfs(root) {
        if (!root) return;
        dfs(root.left);
        res.push(root.val);
        dfs(root.right);
    }
    for (let i = 0; i < res.length - 1; i++) {
        if (res[i] >= res[i + 1]) return false;
    }
    return true;
}

9、判断是不是完全二叉树

  • 若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数
  • 第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树
  • 判断标准:当前为null,不能再继续遍历
function isCompleteTree(root) {
    let res = [root], end = false;
    while (res.length) {
        let cur = res.shift();
        if (!cur) end = true;
        else {
            if (res.length && end) return false;
            res.push(cur.left);
            res.push(cur.right);
        }
    }
    return true;
}

10、二叉搜索树的最近公共祖先

// 二叉搜索树
function lowestCommonAncestor(root, p, q) {
    if (!root) return null;
    let min = Math.min(p, q);
    let max = Math.max(p, q);
    let val = root.val;
    if (val == min || val == max) return val;
    if (min < val && val < max) return val;
    if (val > max) return lowestCommonAncestor(root.left, p, q);
    if (val < min) return lowestCommonAncestor(root.right, p, q);
}


var lowestCommonAncestor = function (root, p, q) {
    if (!root || root == p || root == q) return root;
    let l = lowestCommonAncestor(root.left, p, q);
    let r = lowestCommonAncestor(root.right, p, q);
    return !l ? r : !r ? l : root;
};

11、 序列化二叉树

var serialize = function (root) {
    return rserialize(root, '');
};

var deserialize = function (data) {
    const dataArray = data.split(",");
    return rdeserialize(dataArray);
};

const rserialize = (root, str) => {
    if (root === null) {
        str += "None,";
    } else {
        str += root.val + '' + ",";
        str = rserialize(root.left, str);
        str = rserialize(root.right, str);
    }
    return str;
}

const rdeserialize = (dataList) => {
    if (dataList[0] === "None") {
        dataList.shift();
        return null;
    }
    const root = new TreeNode(parseInt(dataList[0]));
    dataList.shift();
    root.left = rdeserialize(dataList);
    root.right = rdeserialize(dataList);
    return root;
}