Files
Data-Structure/模板//两序重建树.cpp
2025-12-16 20:36:27 +08:00

187 lines
4.6 KiB
C++

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
/*====================================================
= 二叉树节点定义 =
====================================================*/
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
/*====================================================
= 前序 + 中序 重建二叉树(模块一) =
====================================================*/
class BuildFromPreIn {
public:
unordered_map<int, int> pos; // 中序遍历中:值 -> 下标
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
pos.clear();
for (int i = 0; i < n; i++) {
pos[inorder[i]] = i;
}
return dfs(preorder, 0, n - 1, inorder, 0, n - 1);
}
private:
TreeNode* dfs(vector<int>& pre, int preL, int preR,
vector<int>& in, int inL, int inR) {
if (preL > preR) return nullptr;
// 前序第一个元素是当前子树的根
int rootVal = pre[preL];
TreeNode* root = new TreeNode(rootVal);
// 根在中序中的位置
int k = pos[rootVal];
int leftSize = k - inL;
// 构建左子树
root->left = dfs(
pre,
preL + 1,
preL + leftSize,
in,
inL,
k - 1
);
// 构建右子树
root->right = dfs(
pre,
preL + leftSize + 1,
preR,
in,
k + 1,
inR
);
return root;
}
};
/*====================================================
= 中序 + 后序 重建二叉树(模块二) =
====================================================*/
class BuildFromInPost {
public:
unordered_map<int, int> pos; // 中序遍历中:值 -> 下标
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int n = inorder.size();
pos.clear();
for (int i = 0; i < n; i++) {
pos[inorder[i]] = i;
}
return dfs(inorder, 0, n - 1, postorder, 0, n - 1);
}
private:
TreeNode* dfs(vector<int>& in, int inL, int inR,
vector<int>& post,int postL, int postR) {
if (inL > inR) return nullptr;
// 后序最后一个元素是当前子树的根
int rootVal = post[postR];
TreeNode* root = new TreeNode(rootVal);
// 根在中序中的位置
int k = pos[rootVal];
int leftSize = k - inL;
// 构建左子树
root->left = dfs(
in,
inL,
k - 1,
post,
postL,
postL + leftSize - 1
);
// 构建右子树
root->right = dfs(
in,
k + 1,
inR,
post,
postL + leftSize,
postR - 1
);
return root;
}
};
/*====================================================
= 辅助函数:遍历与验证 =
====================================================*/
// 中序遍历(用于验证结构是否正确)
void inorderPrint(TreeNode* root) {
if (!root) return;
inorderPrint(root->left);
cout << root->val << ' ';
inorderPrint(root->right);
}
// 后序遍历
void postorderPrint(TreeNode* root) {
if (!root) return;
postorderPrint(root->left);
postorderPrint(root->right);
cout << root->val << ' ';
}
// 前序遍历
void preorderPrint(TreeNode* root) {
if (!root) return;
cout << root->val << ' ';
preorderPrint(root->left);
preorderPrint(root->right);
}
/*====================================================
= main =
====================================================*/
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
/*
示例测试数据
前序: 3 9 20 15 7
中序: 9 3 15 20 7
后序: 9 15 7 20 3
*/
vector<int> preorder = {3, 9, 20, 15, 7};
vector<int> inorder = {9, 3, 15, 20, 7};
vector<int> postorder = {9, 15, 7, 20, 3};
// 前序 + 中序
BuildFromPreIn solver1;
TreeNode* root1 = solver1.buildTree(preorder, inorder);
// 中序 + 后序
BuildFromInPost solver2;
TreeNode* root2 = solver2.buildTree(inorder, postorder);
// 验证输出
inorderPrint(root1);
cout << '\n';
inorderPrint(root2);
cout << '\n';
return 0;
}