分析:构造树可以用递归的方法来根据条件构造:(主要是考虑好递归的边界问题)
1.从前序数组里可以知道preorder[0]为根节点
2.在中序数组中找到preorder[0]的位置坐标,即preorder[0]==inorder[i]
3.1~i是前序左子树范围 i+1~preorder.length -1 是前序右子树范围
4.0~i-1是中序左子树范围i+1~inorder.length -1 是中序右子树范围
public TreeNode buildTree(int[] preorder, int[] inorder) {
// 递归中止条件:树为空
if(inorder.length == 0 || preorder.length == 0) {
return null;
}
// 根节点的值为前序遍历的第一个元素值
// 创建根节点
TreeNode root = new TreeNode(preorder[0]);
for(int i=0 ;i<inorder.length; ++i) {
// # 用根节点的值去中序数组中查找对应元素下标
if(preorder[0] == inorder[i]) {
// 找出先序遍历的左子树和右子树
// 每次传入的1都会类似向右截取一次数组
int[] preorder_left = Arrays.copyOfRange(preorder,1,i+1);
int[] preorder_right = Arrays.copyOfRange(preorder,i+1,preorder.length);
// 找出中序遍历的左子树和右子树
int[] inorder_left = Arrays.copyOfRange(inorder,0,i);
int[] inorder_right = Arrays.copyOfRange(inorder,i+1,inorder.length);
// 递归遍历左子树
root.left = buildTree(preorder_left,inorder_left);
// 递归遍历右子树
root.right = buildTree(preorder_right,inorder_right);
break;
}
}
return root;
}
根据中序和后序数组构造树的话大同小异,
public TreeNode buildTree(int[] inorder, int[] postorder) {
// 递归中止条件:树为空
if(inorder.length == 0 || postorder.length == 0) {
return null;
}
// 根节点的值为前序遍历的第一个元素值
// 创建根节点
TreeNode root = new TreeNode(postorder[postorder.length - 1]);
for(int i=0 ;i<inorder.length; ++i) {
// # 用根节点的值去中序数组中查找对应元素下标
if(postorder[postorder.length - 1] == inorder[i]) {
// 找出中序遍历的左子树和右子树
int[] inorder_left = Arrays.copyOfRange(inorder,0,i);
int[] inorder_right = Arrays.copyOfRange(inorder,i+1,inorder.length);
// 找出后序遍历的左子树和右子树
int[] postorder_left = Arrays.copyOfRange(postorder,0,i);
int[] postorder_right = Arrays.copyOfRange(postorder,i,postorder.length - 1);
// 递归遍历左子树
root.left = buildTree(inorder_left,postorder_left);
// 递归遍历右子树
root.right = buildTree(inorder_right,postorder_right);
break;
}
}
return root;
}