剑指Offer04 由先序遍历和中序遍历构造二叉树Java版
package offer4;
/**
* 剑指Offer第四题
* <p>
* 给出先序遍历和中序遍历,
* 构建出这个二叉树
* <p>
* 假设输入的先序遍历和中序遍历中都没有重复的数字
* 例如
* 先序遍历{1,2,4,7,3,5,6,8}
* 中序遍历{4,7,2,1,5,3,8,6}
* <p>
* <p>
* 思路分析:
* <p>
* 以以上例子为例
* <p>
* 先序遍历的数组的第一个元素1为二叉树的根节点,
* 中序遍历的根节点1在数组的中间为止,
* 在中序遍历中在根节点左边的元素为左子树,右边为右子树
* <p>
* 因此我们可以将以上数组划分为如下:
* <p>
* 根节点 {1}
* <p>
* 左子树 先序{2,4,7} 中序{4,7,2}
* 右子树 先序{3,5,6,8} 中序{5,3,8,6}
* <p>
* 好,这是第一遍分组
* <p>
* 之后再按照以上的方法找出左子树的根节点,右节点,再进行分组
* 这样一直重复下去
* 例如:
* 左子树 先序{2,4,7} 中序{4,7,2}
* 我们由先序遍历可以确定左子树的根节点,
* 由中序遍历可以将数组再二分得
* <p>
* 左子树根节点{2}
* <p>
* 左子树的左子树 先序{4,7} 中序{4,7}
* 左子树的右子树为空
* <p>
* <p>
* 这有点类似分治策略的思想
*
* @author RhymeChiang
* @date 2018/01/19
**/
public class Offer4 {
/**
* 二叉树节点类
*/
private static class TreeNode {
int element;
TreeNode left;
TreeNode right;
public TreeNode(int element) {
this.element = element;
}
public TreeNode(int element, TreeNode left, TreeNode right) {
this.element = element;
this.left = left;
this.right = right;
}
@Override
public String toString() {
return "TreeNode{" +
"element=" + element +
", left=" + left +
", right=" + right +
'}';
}
}
/**
* 由先序遍历和中序遍历构建二叉树
*
* @param firstTraverse 先序遍历数组
* @param middleTraverse 中序遍历数组
* @return
*/
public static TreeNode buildTree(int[] firstTraverse, int[] middleTraverse) {
TreeNode treeNode = null;
if (firstTraverse.length < 1) {
return null;
} else if (firstTraverse.length == 1) {
return new TreeNode(firstTraverse[0]);
}
int root = firstTraverse[0];
int rootMiddleIndex = -1;
for (int i = 0; i < middleTraverse.length; i++) {
if (middleTraverse[i] == root) {
rootMiddleIndex = i;
break;
}
}
/**
* 根节点构造
*/
treeNode = new TreeNode(root);
/**
* 左子树构建
*/
int[] leftFirst = arrayCopy(firstTraverse, 1, rootMiddleIndex + 1);
int[] leftMiddle = arrayCopy(middleTraverse, 0, rootMiddleIndex);
treeNode.left = buildTree(leftFirst, leftMiddle);
/**
* 构建右子树
*/
int[] rightFirst = arrayCopy(firstTraverse, rootMiddleIndex + 1, firstTraverse.length);
int[] rightMiddle = arrayCopy(middleTraverse, rootMiddleIndex + 1, middleTraverse.length);
treeNode.right = buildTree(rightFirst, rightMiddle);
return treeNode;
}
private static int[] arrayCopy(int[] array, int start, int end) {
int[] newArray = new int[end - start];
int count = 0;
for (int i = start; i < end; i++) {
newArray[count] = array[i];
count++;
}
return newArray;
}
public static void main(String[] args) {
int[] firstTra = {1, 2, 4, 7, 3, 5, 6, 8};
int[] middleTra = {4, 7, 2, 1, 5, 3, 6, 8};
TreeNode treeNode = buildTree(firstTra, middleTra);
System.out.println(treeNode);
}
}