题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不包含重复的数字。例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1,5, 3, 8, 6},则重建出二叉树并输出它的头结点。
知识点:
前序遍历:先访问根节点,再访问左子结点,最后访问右子结点;(根左右)
中序遍历:先访问左子结点,再访问根结点,最后访问右子结点;(左根右)
后序遍历:先访问左子结点,再访问右子结点,最后访问根结点;(左右根)
前序遍历、中序遍历、后序遍历都可以用递归和循环进行实现。故树的遍历有3种方式6种实现。
解题思路:
题目中给了我们先序遍历和中序遍历;在二叉树的前序遍历中,第一个数字总是树的根结点的值。但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。因此我们需要扫描中序遍历序列,才能找到根结点的值。
代码如下:
public class test {
public static void main(String[] args) {
int pre[] = {1, 2, 4, 7, 3, 5, 6, 8};
int mid[] = {4, 7, 2, 1, 5, 3, 8, 6};
BNode treeNode = rebuild(pre, mid);
System.out.println(treeNode);
}
public static BNode rebuild(int[] pre, int[] mid) {
if(pre == null || mid == null) {
return null;
}
BNode root = rebuildTree(pre,0,pre.length-1,mid,0,mid.length-1);
return root;
}
public static BNode rebuildTree(int[] pre,int ps,int pe,int[] mid,int ms,int me) {
if(ps>pe || ms>me) {
return null;
}
BNode root = new BNode(pre[ps]);
for(int i=ms;i<=me;i++) {
if(pre[ps] == mid[i]) {
root.left = rebuildTree(pre,ps+1,ps+(i-ms),mid,ms,i-1);
root.right = rebuildTree(pre,ps+1+(i-ms),pe,mid,i+1,me);
}
}
return root;
}
public static class BNode{
public BNode left;
public BNode right;
public int data;
BNode(int data){
this.left = null;
this.right = null;
this.data = data;
}
public String toString() {
return "BNode [data=" + data + ", left=" + left + ", right=" + right
+ "]";
}
}
}