1、逻辑梳理
1、后序遍历的特点:后序遍历的最后一个节点是根节点
2、中序遍历的特点:根节点将中序序列分成左子树和右子树两部分
具体步骤
1、从后序遍历序列的最后一个节点取出根节点
2、在中序遍历序列中找到根节点的位置,这个位置的左边部分是左子树,右边部分是右子树
3、递归构建左子树和右子树,重复以上步骤
注意 : 需要先构建右子树,因为后序遍历是左、右、根;逆序过来是需要根、右、左
2、核心代码
public class BinaryTreeBuilder {
private Map<Integer, Integer> inorderIndexMap;
private int postIndex;
public TreeNode buildTree(int[] inorder, int[] postorder) {
// 构建中序遍历值和索引的映射,方便快速查找根节点的位置
inorderIndexMap = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
inorderIndexMap.put(inorder[i], i);
}
postIndex = postorder.length - 1; // 初始化后序遍历的根节点索引
return buildTreeHelper(postorder, 0, inorder.length - 1);
}
private TreeNode buildTreeHelper(int[] postorder, int inorderStart, int inorderEnd) {
// 递归终止条件
if (inorderStart > inorderEnd) {
return null;
}
// 从后序遍历中获取当前根节点
int rootVal = postorder[postIndex--];
TreeNode root = new TreeNode(rootVal);
// 在中序遍历中找到根节点的索引
int inorderRootIndex = inorderIndexMap.get(rootVal);
// 递归构建右子树和左子树
root.right = buildTreeHelper(postorder, inorderRootIndex + 1, inorderEnd);
root.left = buildTreeHelper(postorder, inorderStart, inorderRootIndex - 1);
return root;
}
public static void main(String[] args) {
int[] inorder = {9, 3, 15, 20, 7}; // 左根右
int[] postorder = {9, 15, 7, 20, 3}; // 左右根
BinaryTreeBuilder builder = new BinaryTreeBuilder();
TreeNode root = builder.buildTree(inorder, postorder);
// 输出树的结构
printTree(root);
}
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
// 辅助方法:输出树的前序遍历结果
private static void printTree(TreeNode node) {
if (node != null) {
System.out.print(node.val + " ");
printTree(node.left);
printTree(node.right);
}
}
3、结果输出
3 9 20 15 7
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。