107 lines
3.4 KiB
C++
107 lines
3.4 KiB
C++
#include <cassert>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
|
|
class BinaryTree {
|
|
public:
|
|
struct Node {
|
|
int value = -1;
|
|
Node *father = nullptr, *left = nullptr, *right = nullptr;
|
|
};
|
|
|
|
Node* root = nullptr;
|
|
|
|
void reconstruct(const std::vector<int>& inorder_traversal, const std::vector<int>& postorder_traversal) {
|
|
assert(inorder_traversal.size() == postorder_traversal.size());
|
|
root = reconstruct_node(
|
|
inorder_traversal, postorder_traversal,
|
|
0, inorder_traversal.size(),
|
|
0, inorder_traversal.size());
|
|
}
|
|
|
|
[[nodiscard]] std::vector<int> preorder_traversal() {
|
|
std::vector<int> result;
|
|
preorder_dfs(root, result);
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
Node* reconstruct_node(
|
|
const std::vector<int>& inorder_traversal, const std::vector<int>& postorder_traversal,
|
|
std::size_t inorder_begin, std::size_t inorder_end, std::size_t postorder_begin, std::size_t postorder_end
|
|
) {
|
|
if (inorder_end - inorder_begin == 1) {
|
|
return new Node({.value = inorder_traversal[inorder_begin]});
|
|
}
|
|
if (inorder_end == inorder_begin) { return nullptr; }
|
|
auto in_begin = inorder_traversal.begin() + inorder_begin;
|
|
auto in_end = inorder_traversal.begin() + inorder_end;
|
|
auto root_idx = std::find(
|
|
in_begin, in_end,
|
|
postorder_traversal[postorder_end - 1]
|
|
) - inorder_traversal.begin();
|
|
auto left_length = root_idx - inorder_begin;
|
|
auto right_length = inorder_end - root_idx - 1;
|
|
|
|
Node* left_node = reconstruct_node(
|
|
inorder_traversal, postorder_traversal,
|
|
inorder_begin, root_idx, postorder_begin, postorder_begin + left_length
|
|
);
|
|
Node* right_node = reconstruct_node(
|
|
inorder_traversal, postorder_traversal,
|
|
root_idx + 1, inorder_end, postorder_end - 1 - right_length, postorder_end - 1
|
|
);
|
|
|
|
Node* node = new Node({
|
|
.value = inorder_traversal[root_idx],
|
|
.left = left_node, .right = right_node,
|
|
});
|
|
if (left_node != nullptr) { left_node->father = node; }
|
|
if (right_node != nullptr) { right_node->father = node; }
|
|
return node;
|
|
}
|
|
|
|
void preorder_dfs(Node* node, std::vector<int>& result) {
|
|
if (node == nullptr) { return; }
|
|
result.push_back(node->value);
|
|
preorder_dfs(node->left, result);
|
|
preorder_dfs(node->right, result);
|
|
}
|
|
};
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& os, const std::vector<int>& vector) {
|
|
for (int x : vector) { os << x << ' '; }
|
|
return os;
|
|
}
|
|
|
|
int main() {
|
|
std::ios::sync_with_stdio(false);
|
|
std::cin.tie(nullptr);
|
|
|
|
std::vector<int> inorder_traversal, postorder_traversal;
|
|
|
|
std::string lines[2];
|
|
std::getline(std::cin, lines[0]);
|
|
std::getline(std::cin, lines[1]);
|
|
|
|
std::istringstream iss1(lines[0]), iss2(lines[1]);
|
|
int temp;
|
|
while (iss1 >> temp) {
|
|
inorder_traversal.push_back(temp);
|
|
}
|
|
while (iss2 >> temp) {
|
|
postorder_traversal.push_back(temp);
|
|
}
|
|
|
|
std::clog << inorder_traversal << std::endl << postorder_traversal << std::endl;
|
|
|
|
BinaryTree binary_tree;
|
|
binary_tree.reconstruct(inorder_traversal, postorder_traversal);
|
|
std::cout << binary_tree.preorder_traversal() << std::endl;
|
|
|
|
return 0;
|
|
}
|