根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
思路:
中序遍历步骤:左子树、根节点、右子树
后序遍历步骤:左子树、右子树、根节点
后序遍历数组的最后一个元素一定是根节点
在找到根节点在中序遍历中的下标,找出左右子树的节点个数,依次遍历
代码实现:
public TreeNode buildTree(int[] inorder, int[] postorder) {
//空数组直接返回
if(inorder.length == 0 || postorder.length == 0){
return null;
}
//Map存储索引信息
HashMap<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
//左开右闭 所以开始的指针是-1,结束指针是长度-1。
return Bulid(postorder , -1, postorder.length -1, inorder, -1,inorder.length-1 , map);
}
//参数 : 后序遍历数组、后序遍历前指针,后序遍历后指针,中序遍历数组、中序遍历前指针,中序遍历后指针,Map集合
public TreeNode Bulid(int[] post,int pstart, int pend, int[] in, int istart,int iend,HashMap<Integer,Integer> map){
//终止条件 当后序遍历的指针重合或者中序遍历的指针重合
if(pstart == pend || istart == iend){
return null;
}
//找到根节点 根节点位于后序遍历数组的最后一个元素
int rootVal = post[pend];
//创建一颗新树
TreeNode root = new TreeNode(rootVal);
//找到当前根节点在中序遍历数组中的位置
int root_index = map.get(rootVal);
//确定右子树有多少个节点
int rightNum = iend - root_index;
//因为是由后往前走的,所以先求右子树 范围是左开右闭,所以要-1 递归右子树
root.right = Bulid(post, pend - rightNum -1 ,pend -1,in,root_index,iend,map);
//递归左子树
root.left = Bulid(post,pstart,pend - rightNum -1,in,istart,root_index-1,map);
return root;
}