给定两个序列,还原二叉树
题型如下所示:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析:前序可确定根,中序确定左右子树,递归执行即可。
详细请看演示图:
从前序中逐个节点遍历,从中序序列中找到对应与第一步得到的节点,划分左右子树
再执行一遍上述过程:
再执行一遍上述过程:
当做到这里的时候是不是就已经还原了以 Root=1 的左子树了呢?
下面的工作就由读者自行完成吧。
树还原的样子:
接下来是根据上面的图的动态演变概括出算法(即操作步骤):
第一步,从前序中逐个节点遍历;
第二步,从中序序列中找到对应与第一步得到的节点;
第三步,从中序中找到该节点后,以该节点为子树的根,在其左边的为左子树,右边的为右子树;
第四步,递归执行前三步,直到中序节点的前序遍历完。
核心代码如下:
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root = reConstructBinaryTree ( pre,0,pre.length-1,in,0,in.length-1 );
return root;
}
public TreeNode reConstructBinaryTree(int [] pre,int stapre,int endpre,int [] in,int stain,int endin) {
if (stapre > endpre || stain > endin) return null;
TreeNode root = new TreeNode ( pre[stapre] );
for (int i=stain; i<=endin; i++){
if (in[i] == pre[stapre]){
root.left = reConstructBinaryTree ( pre,stapre+1,stapre+i-stain,in,stain,i-1 );
root.right = reConstructBinaryTree ( pre, i-stain+stapre+1, endpre, in, i+1, endin );
}
}
return root;
}
全部代码:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode () {
}
public int getVal () {
return val;
}
public void setVal (int val) {
this.val = val;
}
public TreeNode getLeft () {
return left;
}
public void setLeft (TreeNode left) {
this.left = left;
}
public TreeNode getRight () {
return right;
}
public void setRight (TreeNode right) {
this.right = right;
}
TreeNode(int x) {
val = x;
}
public void display(){
System.out.print (val + " ");
}
}
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root = reConstructBinaryTree ( pre,0,pre.length-1,in,0,in.length-1 );
return root;
}
public TreeNode reConstructBinaryTree(int [] pre,int stapre,int endpre,int [] in,int stain,int endin) {
if (stapre > endpre || stain > endin) return null;
TreeNode root = new TreeNode ( pre[stapre] );
for (int i=stain; i<=endin; i++){
if (in[i] == pre[stapre]){
root.left = reConstructBinaryTree ( pre,stapre+1,stapre+i-stain,in,stain,i-1 );
root.right = reConstructBinaryTree ( pre, i-stain+stapre+1, endpre, in, i+1, endin );
}
}
return root;
}
//先序遍历
public void preOrder(TreeNode treeNode){
if (treeNode != null){
treeNode.display ();
preOrder ( treeNode.getLeft () );
preOrder ( treeNode.getRight () );
}
}
//中序遍历
public void inOrder(TreeNode treeNode){
if (treeNode != null){
inOrder ( treeNode.getLeft () );
treeNode.display ();
inOrder ( treeNode.getRight () );
}
}
//后序遍历
public void endOrder(TreeNode treeNode){
if (treeNode != null){
endOrder ( treeNode.getLeft () );
endOrder ( treeNode.getRight () );
treeNode.display ();
}
}
public static void main (String[] args) {
Solution solution = new Solution ();
TreeNode root = null;
int[] pre = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
root = solution.reConstructBinaryTree ( pre,in );
System.out.println ("前序遍历: ");
solution.preOrder ( root );
System.out.println ();
System.out.println ("中序遍历: ");
solution.inOrder ( root );
System.out.println ();
System.out.println ("后序遍历: ");
solution.endOrder ( root );
}
}
运行结果(检查):