2020.04.26
题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如:前序遍历序列{ 1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},重建出下图所示的二叉树并输出它的头结点。
解题思路:
首先明确的是要用递归的方法,一定要记住递归一定要设置出口,做好代码健壮性
从前序遍历中找到根节点
遍历中序遍历找到根节点的位置记录(就叫它index)
以左子树为例子
左子树的长度中序遍历的index减去中序开始的位置
左子树的参数{前序序列,当前根位置+1,当前根位置+中序遍历的长度,中序遍历,中序遍历开始的位置,中序遍历的index-1}
右子树以此类推
package offer06;
import org.junit.Test;
class Node {
int value;
Node leftChild;
Node rightNode;
public Node() {
// TODO 自动生成的构造函数存根
}
public Node(int value) {
this.value = value;
}
}
public class TreeTest {
public Node createTree(int[] beforeOrder , int [] afterOrder) {
if(beforeOrder.length!=afterOrder.length||beforeOrder.length<=0) {
throw new RuntimeException("输入的遍历数组不合法");
}
return createTreeRoot(beforeOrder,0,beforeOrder.length-1,afterOrder,0,afterOrder.length-1);
}
public Node createTreeRoot(int[] beforeOrder,int bstart,int bend,int[] afterOrder,int astart,int aend) {
if(bstart > bend) {
//作为遍历的结束
return null;
}
int value = beforeOrder[bstart];//当前遍历的根的值
int index = astart;
while (index<=aend && afterOrder[index]!=value) {
index++;
}
if(index > aend) {
throw new RuntimeException("中序遍历中没有前序遍历的根");
}
Node rootNode =new Node(value);
//左子树的长度index-astart
int test1 = bstart+1;//前序遍历的根的位置
int test2 = bstart+(index-astart);//前序遍历结束的位置
rootNode.leftChild = createTreeRoot(beforeOrder,test1 ,test2,afterOrder,astart ,index-1);
rootNode.rightNode = createTreeRoot(beforeOrder,bstart+1+(index-astart),bend ,afterOrder,index+1,aend);
return rootNode;
}
public static void orderPrint(Node rootNode) {
if(rootNode != null) {
orderPrint(rootNode.leftChild);
System.out.print(rootNode.value);
orderPrint(rootNode.rightNode);
}
}
// 普通二叉树
// 1
// / \
// 2 3
// / / \
// 4 5 6
// \ /
// 7 8
@Test
public void test1() {
int[] preorder1 = {1, 2, 4, 7, 3, 5, 6, 8};
int[] inorder1 = {4, 7, 2, 1, 5, 3, 8, 6};
Node root = createTree(preorder1, inorder1);
orderPrint(root);
int[] preorder2 = {};
int[] inorder2 = {};
Node root2 = createTree(preorder2, inorder2);
orderPrint(root2);
}
}