# 重建二叉树

leetcode - 105. 从前序与中序遍历序列构造二叉树 (opens new window)

# 题目

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

# 思路

  • 前序遍历:根-左-右
  • 中序遍历:左-根-右

因此

  • 对于preorder,每个首元素即为一个子树的根元素
  • 对于inorder,查找preorder中的根元素
    • 左边为preorder当前根元素的左子树
    • 右边为preorder当前根元素的右子树

据此 递归 构造出一颗二叉树即可: - 终止条件: 前序和中序数组为空 - 通过前序数组第一个元素找到根节点root,找到root在中序遍历的位置,再将前序数组和中序数组分成两半,递归的处理前序数组左边和中序数组左边,递归的处理前序数组右边和中序数组右边。

# 代码

# Johninch

function Node(val) {
    this.val = val;
    this.left = this.right = null;
}

function reConstruct(preorder, inorder) {
    if(preorder.length === 0){
        return null;
    }
    if(preorder.length === 1){
        return new Node(preorder[0]);
    }
    const value = preorder[0];
    const root = new Node(value);
    const index = inorder.indexOf(value);

    // slice 包含从 start 到 end(不包括该元素)
    const inLeft = inorder.slice(0, index);
    const inRight = inorder.slice(index + 1); // 去掉根
    const preLeft = preorder.slice(1, index + 1); // 去掉根
    const preRight = preorder.slice(index + 1);

    root.left = reConstruct(preLeft, inLeft);
    root.right = reConstruct(preRight, inRight);

    return root;
}

# niannings

export function rebuildTree(frontEachList: any[], middleEachList: any[]) {
    const tree = new BinaryTree();
    if (frontEachList.length === 0) return tree;
    tree.root = rebuild(frontEachList, middleEachList);

    function rebuild(f: any[], m: any[]) {
        const v = f[0];
        const newNode = new BinaryTreeNode(v);
        const sliceIndex = m.indexOf(v);
        const l = f.slice(1, sliceIndex + 1);
        const r = f.slice(sliceIndex + 1);
        if (l.length) {
            newNode.left = rebuild(l, m.slice(0, sliceIndex));
        }
        if (r.length) {
            newNode.right = rebuild(r, m.slice(sliceIndex + 1));
        }
        return newNode;
    }
    return tree;
}

# febcat

const reBuild = (inorder, preorder) => {
  let newTree = new Tree();

  if (!preorder.length) {
    return newTree;
  }

  const loop = (inorder, preorder) => {
    let data = preorder[0];
    let root = new Node(data);
    let num = inorder.indexOf(data);
    let inorderLeft = inorder.slice(0, num);
    let inorderRight = inorder.slice(num + 1);
    let preorderLeft = preorder.slice(1, inorderLeft.length + 1);
    let preorderRight = preorder.slice(preorderLeft.length + 1);

    if (inorderLeft.length) {
      root.left = loop(inorderLeft, preorderLeft);
    }

    if (inorderRight.length) {
      root.right = loop(inorderRight, preorderRight);
    }

    return root;
  };

  newTree.root = loop(inorder, preorder);

  return newTree;
};
Last Updated: 4/9/2020, 4:16:49 PM