题目:输入某二叉树的前序和中序遍历结果,请重建该二叉树
如二叉树
前序遍历为 1,2,4,7,3,5,6,8
中序遍历为 4,7,2,1,5,3,8,6
前序遍历的特点:先遍历根节点,然后遍历左孩子节点,然后遍历右孩子节点。
中序遍历的特点:先遍历左孩子节点,然后遍历根节点,最后遍历右孩子节点。
解题过程
前序遍历先遍历根节点,可以获取根节点的值,循环找到中序遍历的根节点的位置,那么中序遍历数组的根节点左边的节点即为左孩子节点,右边的节点即为右孩子节点。
然后寻找左孩子节点的树结构,右孩子的树结构。直到只有一个元素
int[] preTraversal, int[] inTraversal, int preStart, int preEnd, int inStart, int inEnd 前序遍历数组 ,中序遍历数组,前序遍历开始,前序遍历结束 中序遍历开始 中序遍历结束
以示例二叉树为例,从前序遍历获取根节点的值,对比中序遍历根节点位置,
如题 rootValue=1, rootIndex=3
前序遍历的左孩子节点对应的下标为 [1,2,3], 右孩子节点[4,5,6,7]
中序遍历的左孩子节点对应的下标[0,1,2],右孩子[4,5,6,7]
第二轮:遍历1的左孩子节点(关注有颜色的值)rootValue=2,rootIndex=2
前序遍历的左孩子节点对应的下标为[2,3],右孩子节点 无
中序遍历的左孩子节点对应的下标[0,1],右孩子无
第三轮:遍历2的左孩子节点 rootValue=4,rootIndex=0
前序遍历的左孩子节点对应的下标为无,右孩子节点 3
中序遍历的左孩子节点对应的下标无,右孩子无1
第四轮:遍历4的右孩子节点 rootValue7,rootIndex=1
只有一个节点返回.
代码
/**
* 中序 4,7,2,1,5,3,8,6 调用
*/
public void reBuildBinaryTree(int[] preTraversal, int[] inTraversal) throws Exception {
if (preTraversal == null || inTraversal == null || preTraversal.length == 0
|| inTraversal.length == 0 || preTraversal.length != inTraversal.length) {
return;
}
TreeNode tree = buildBinaryTree(preTraversal, inTraversal, 0,
preTraversal.length - 1, 0, preTraversal.length - 1);
prePrintTree(tree);
System.out.println();
inPrintTree(tree);
System.out.println();
}
//构建核心
public TreeNode buildBinaryTree(int[] preTraversal, int[] inTraversal, int preStart, int preEnd, int inStart, int inEnd) throws Exception {
if (preStart > preEnd || inStart > inEnd) {
return null;
}
int value = preTraversal[preStart];
TreeNode tree = new TreeNode(value);
int rootIndex = inStart;
// 在中序遍历中获取根节点位置
while (rootIndex <= inEnd && value != inTraversal[rootIndex]) {
rootIndex++;
}
// 寻找根节点的左子节点
if (rootIndex <= inEnd) {
tree.left = buildBinaryTree(preTraversal, inTraversal, preStart + 1, preStart + rootIndex - inStart, inStart, rootIndex - 1);
// 寻找根节点的右子节点
tree.right = buildBinaryTree(preTraversal, inTraversal, preStart + rootIndex - inStart + 1, preEnd, rootIndex + 1, inEnd);
}
return tree;
}
前序中序输出
// 前序输出
public void prePrintTree(TreeNode tree) {
if (tree == null) {
return;
}
System.out.print(tree.value + " ");
prePrintTree(tree.left);
prePrintTree(tree.right);
}
//中序输出
public void inPrintTree(TreeNode tree) {
if (tree == null) {
return;
}
inPrintTree(tree.left);
System.out.print(tree.value + " ");
inPrintTree(tree.right);
}
测试用例
// main函数测试用例
public static void main(String[] args) throws Exception {
int[] prearr = new int[]{1, 2, 4, 7, 3, 5, 6, 8};
int[] inarr = new int[]{4, 7, 2, 1, 5, 3, 8, 6};
int[] prearr1 = new int[]{1, 2, 3, 4, 5};
int[] inarr1 = new int[]{5, 4, 3, 2, 1};
int[] prearr2 = new int[]{1, 2, 3, 4, 5};
int[] inarr2 = new int[]{1, 2, 3, 4, 5};
// 异常测试
int[] prearr3 = new int[]{1, 2, 3, 4, 5};
int[] inarr3 = new int[]{5, 4, 3, 2, 6};
BinaryTree binaryTree = new BinaryTree();
binaryTree.reBuildBinaryTree(prearr, inarr);
binaryTree.reBuildBinaryTree(prearr1, inarr1);
binaryTree.reBuildBinaryTree(prearr2, inarr2);
// 异常测试
binaryTree.reBuildBinaryTree(prearr3, inarr3);
}
class TreeNode {
TreeNode left;
TreeNode right;
int value;
public TreeNode(int value) {
this.value = value;
}
}