给出需要重建的二叉树的前序遍历和中序遍历,需要还原该二叉树。
思路:
前序遍历:【根】【左子树】【右子树】
中序遍历:【左子树】【根】【右子树】
故前序遍历的第一个元素就是根的数值,获取根植后在中序遍历中就可以找到左、右子树个数等信息了。
对于二叉树生成需要如下信息(二叉树根的下标是基于前序遍历生成的,中序遍历用于已知根后,判断该二叉树所包含的左右子树所用范围):
函数TreeNode build(int root, int left, int right)
参数意义:
root:根节点在前序遍历中的下标
left:该树在中序遍历中的左边界
right:该树在中序遍历中的右边界
public TreeNode buildTree(int[] preorder, int[] inorder) {
preoders = preorder;
for (int i = 0; i < inorder.length; i++) {
inordered.put(inorder[i], i);
}
return build(0, 0, preorder.length - 1);
}
TreeNode build(int root, int left, int right) {
if (left > right) {
return null;
}
int rootNum = preoders[root];
TreeNode node = new TreeNode(rootNum);
int rootPos = inordered.get(rootNum);
node.left = build(root + 1, left, rootPos - 1);
node.right = build(rootPos - left + root + 1, rootPos + 1, right);
return node;
}
第一次生成:根为前序0下标,左子树范围从0到长度-1
左子树生成:
根:在前序遍历将root下标+1
左边界:和传进来的左边界相同
右边界:在中序遍历中根下标即rootPos-1
右子树生成:
根:在前序遍历中将根root+左子树节点数量+1
(左子树节点数量=在中序遍历中根下标rootPos-左边界left)
左边界:中序遍历中根下标即rootPos+1
右边界:和传进来的右边界相同
(上述根节点依据前序遍历图推导理解,边界根据中序遍历图推导理解)
用递归函数持续生成即可重建二叉树。
注:
每一次的生成实际只需要二叉树根节点的值,传进的左、右边界主要是用于判断是否还有子树需要生成。
根节点值获取:实际包括第一次,每当查找一个二叉树的根值时,该树的前序遍历的第一个值就是根值。这也就是为什么函数参数中根的下标是依据前序遍历来推导的。
左右边界利用中序遍历只需要对中序遍历中的根节点下标进行±1操作就可以了。