已知树的前/后序 + 中序遍历, 构造出整棵二叉树
特殊: 如果仅仅知道 前序 + 后序遍历 是不能唯一确定二叉树的。
比如前序 [1, 2]
后序 [2, 1]
二叉树可以为:
1
/
2
或者
1
\
2
本文以 后序遍历 + 前序遍历 为例子 进行讲解
例题链接: Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
二叉树构造流程:
- 先通过后序遍历确定二叉树的根(包括小二叉树的根)
- 然后根据这个根将中序遍历分为左右子树
- 再将左右子树按照同样的方法进行构造
首先建立节点3
它的右子树为 1 过程。
1 中后序遍历的最后一个节点又是该子树的根。
依次首先将右子树遍历完成后再遍历左子树(这样正符合后序遍历的顺序,所以依次从后向前遍历后序遍历列表即可)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private int index = 0;
public TreeNode buildTree(int[] inorder, int[] postorder) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
index = postorder.length-1;
int index = 0;
for(int val:inorder){
map.put(val, index++);
}
return build(0, inorder.length-1, inorder, postorder, map);
}
public TreeNode build(int start, int end, int[] inorder, int[] postorder, HashMap<Integer, Integer> map){
if(start > end){
return null;
}
//从后向前依次获取后序遍历
int val = postorder[index];
index--;
//获得后序遍历中根在中序遍历中位置,划分为左右子树
int mid = map.get(val);
//建立该根节点
TreeNode root = new TreeNode(val);
//依次建立根节点的两个儿子
root.right = build(mid+1, end, inorder, postorder, map);
root.left = build(start, mid-1, inorder, postorder, map);
//返回该根节点
return root;
}
}
前序遍历 + 中序遍历 的原理一样,只是从前向后依次遍历前序遍历列表即可。