从前序和中序遍历重建二叉树:C++ 递归与哈希表解析
一、题目背景
已知一棵二叉树的:
- 前序遍历序列
preorder - 中序遍历序列
inorder
并且树中不存在重复节点值,要求 重建这棵二叉树,返回根节点 TreeNode*。
二、关键性质回顾
二叉树的遍历有这些性质(这里用到前序 + 中序):
- 前序遍历(Preorder):
顺序是:
根节点 -> 左子树 -> 右子树所以preorder[0]一定是整棵树的 根节点。 - 中序遍历(Inorder):
顺序是:
左子树 -> 根节点 -> 右子树在中序序列中,根节点左边的部分是'左子树',右边的部分是'右子树'。
因为题目保证所有节点值互不相同,所以我们可以用一个哈希表
unordered_map<int, int> pos;
来把「节点值」映射到「它在中序遍历中的下标」,方便 O(1) 查找。
三、整体思路
- 预处理:
把
inorder每个值所在的位置存进哈希表pos,方便通过值快速找到它在中序序列中的下标。 - 前序的指针
preIndex: 因为前序遍历顺序是:根 → 左 → 右,我们可以维护一个全局下标preIndex,每次从preorder[preIndex]取当前子树的根,然后preIndex++,继续构造子树。- 如果
l > r,说明这个区间是空的,对应的子树为空,返回nullptr。 - 否则:
- 取当前根:
val = preorder[preIndex++] - 在中序中找到根的位置:
mid = pos[val] - 左子树对应中序区间
[l, mid - 1] - 右子树对应中序区间
[mid + 1, r] - 递归生成左右子树,并挂到根上。
- 取当前根:
- 如果
递归构造子树:
用一个函数 dfs(l, r) 表示:
根据「中序遍历的区间
[l, r]」,构造出这一段对应的子树,并返回这棵子树的根节点指针。
四、代码实现解析
代码如下:
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<>& inorder) {
n = preorder.();
unordered_map<,> pos;
pos.(n * );
( i = ; i < n; ++i) pos[inorder[i]] = i;
preIndex = ;
dfs = [&](&& self, l, r) -> TreeNode* {
(l > r) ;
val = preorder[preIndex++];
mid = pos[val];
TreeNode* root = (val);
root->left = (self, l, mid - );
root->right = (self, mid + , r);
root;
};
(dfs, , n - );
}
};

