数算!
This commit is contained in:
1 parent
ca6daa582c
commit
e0c09e0c7b
22 files changed
+1344
-105
No files matched your search
@@ -0,0 +1,106 @@
|
||||
#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;
|
||||
}
|
||||
Reference in new issue
Block a user