题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:先序序列的第一个节点是当前子树的根节点,然后遍历中序序列找到这个节点,中序序列的这个节点左边为新的左子树,右边为新的右子树。然后递归实现上述过程即可。
注意要点:
- 异常点的判断,序列为空,两序列长度不等,长度小于等于0。
- 通过左子树长度计算新的左子树先序最后一个点的位置,这一步很重要,这里一定要新设变量保存这个位置,因为当前保存先序最后一个位置的变量还需要作为新的右子树最有一个节点位置。
- 最后指定左子树,右子树执行递归的时候,头脑要清醒,不要写成了:
if (leftLength > 0) {
return rebuild(pre, in, preHead + 1, leftPreEnd, inHead, rootIndex - 1);
}
这么写彻底玩完。
重建二叉树的参考代码如下:
public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre== null || in == null) {
return null;
}
if (pre.length <= 0 || in.length <= 0 || pre.length != in.length) {
return null;
}
return rebuild(pre, in, 0, pre.length - 1, 0, in.length - 1);
}
private static TreeNode rebuild(int[] pre, int[] in, int preHead, int preEnd, int inHead, int inEnd) {
TreeNode node = new TreeNode(pre[preHead]);
node.left = null;
node.right = null;
if (preHead == preEnd) {
if (inHead == inEnd) {
return node;
}else {
return null;//错误
}
}
int rootIndex = inHead;
while(rootIndex <= inEnd && in[rootIndex] != pre[preHead])
rootIndex ++;
if (rootIndex > inEnd) {
return null;//错误
}
int leftLength = rootIndex - inHead;//左子树长度
int leftPreEnd = preHead + leftLength;//更新新的右子树位置
if (leftLength > 0) {
node.left = rebuild(pre, in, preHead + 1, leftPreEnd, inHead, rootIndex - 1);
}
if (preEnd - preHead > leftLength ) {//左子树长度小于序列的长度
node.right = rebuild(pre, in, leftPreEnd + 1, preEnd, rootIndex + 1, inEnd);
}
return node;
}
树结构的java代码:
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
public void printTreeNode(TreeNode node) {//先序
System.out.println(node.val);
if (node.left != null) {
printTreeNode(node.left);
}
if (node.right != null) {
printTreeNode(node.right);
}
}
}
完整的项目参考代码:
public class RebuildBiTree {
public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre== null || in == null) {
return null;
}
if (pre.length <= 0 || in.length <= 0 || pre.length != in.length) {
return null;
}
return rebuild(pre, in, 0, pre.length - 1, 0, in.length - 1);
}
private static TreeNode rebuild(int[] pre, int[] in, int preHead, int preEnd, int inHead, int inEnd) {
TreeNode node = new TreeNode(pre[preHead]);
node.left = null;
node.right = null;
if (preHead == preEnd) {
if (inHead == inEnd) {
return node;
}else {
return null;//错误
}
}
int rootIndex = inHead;
while(rootIndex <= inEnd && in[rootIndex] != pre[preHead])
rootIndex ++;
if (rootIndex > inEnd) {
return null;//错误
}
int leftLength = rootIndex - inHead;
int leftPreEnd = preHead + leftLength;
if (leftLength > 0) {
node.left = rebuild(pre, in, preHead + 1, leftPreEnd, inHead, rootIndex - 1);
}
if (preEnd - preHead > leftLength ) {
node.right = rebuild(pre, in, leftPreEnd + 1, preEnd, rootIndex + 1, inEnd);
}
return node;
}
public static void main(String[] args) {
int[] pre = {1,2,3,4,5,6,7};
int[] in = {3,2,4,1,6,5,7};
TreeNode lNode = reConstructBinaryTree(pre,in);
lNode.printTreeNode(lNode);
}
}