题目:
输入二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.
假设输入的前序遍历和中序遍历的结果都不含重复的数字.
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
则重建出二叉树,并输出头结点.
思路:
根据先序遍历的第一个结点1为根节点,可以将中序遍历序列划分为两个部分,左侧{4,7,2}是根节点的左子树中序序列,右侧{5,3,8,6}是根节点的右子树中序序列.
同时,也可以将先序遍历序列划分为三部分,1为根节点,{2,4,7}为左子树的先序序列,{3,5,6,8}为右子树的先序序列.
这样就可以把一个较大规模的问题转化为更小规模的问题.
知道先序序列{2,4,7},中序序列{4,7,2},重建二叉树.
知道先序序列{3,5,6,8},中序序列{5,3,8,6},重建二叉树.
这两个二叉树是以1为根节点的.
根据这种思路,很容易写出来递归代码.
private static class Node {
Node left;
Node right;
char value;
}
static Node rebuild(String preOrder, String inOrder) {
if (preOrder == null || inOrder == null) {
return null;
}
if (preOrder.length() == 0 || inOrder.length() == 0) {
return null;
}
if (preOrder.length() != inOrder.length()) {
return null;
}
Node root = new Node();
root.value = preOrder.charAt(0);
root.left = null;
root.right = null;
int preRootIndex = preOrder.indexOf(root.value);
int inRootIndex = inOrder.indexOf(root.value);
String leftInOrder = inOrder.substring(0, inRootIndex);
String rightInOrder = inOrder.substring(inRootIndex + 1, inOrder.length());
int leftLen = leftInOrder.length();
String leftPreOrder = preOrder.substring(preRootIndex + 1, preRootIndex + 1 + leftLen);
String rightPreOrder = preOrder.substring(preRootIndex + 1 + leftLen, preOrder.length());
if (leftPreOrder.length() > 0 && leftInOrder.length() > 0) {
root.left = rebuild(leftPreOrder, leftInOrder);
}
if (rightPreOrder.length() > 0 && rightInOrder.length() > 0) {
root.right = rebuild(rightPreOrder, rightInOrder);
}
return root;
}