subject
Title Description
A binary tree is given by traversing in middle and after order, and now the following is done:
-
UPDATE A B, changes the weight of the node in the binary tree corresponding to the A position (subscript numbered from the beginning) in the middle traversal to B
-
QUERY, which asks the weights of all nodes in the tree and the sum of the path weights from the root node to that node
-
STOP, stop operation, STOP operation must appear at the end
The inputs of middle and post-order traversals guarantee that the weight values of leaf nodes are different. However, if an UPDATE operation later exists, the UPDATE operation may result in two or more leaf nodes having the same weight.
input
Test data has multiple groups
For each set of test data,
The first line enters the result of an ordered traversal through this binary tree
The second line enters the result of the postorder traversal of this binary tree
Next, each row enters an operation until the STOP operation is entered to end the input of this set of test data. Among them, QUERY operation number <= 2, total operation number <= 104
Input is processed to the end of the file (EOF)
output
For each set of test data:
For QUERY operations, the weights of the output node and the sum of the path weights from the root node to that node are traversed in an intermediate order. Here, we consider that the sum of the path weights from the root node to itself is the weight of the root node
sample input
3 2 1 4 5 7 6
3 1 2 5 6 7 4
UPDATE 5 99
UPDATE 6 123
UPDATE 1 37
QUERY
UPDATE 1 36
QUERY
STOP
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
QUERY
STOP
255
255
STOP
sample output
37 43
2 6
1 7
4 4
99 226
123 127
6 133
36 42
2 6
1 7
4 4
99 226
123 127
6 133
7 12
8 31
11 23
3 26
5 5
16 33
12 17
18 35
Code
#include<iostream> #include<string> #include<vector> using namespace std; struct Node { int data; int pos; Node* left; Node* right; Node() :left(nullptr), right(nullptr) {} Node(int theData) :left(nullptr), right(nullptr), data(theData) {} }; class biTree { private: Node* root; Node* createBiTree(vector<int>& inorder, vector<int>& postorder) { // Step One if (postorder.size() == 0) return nullptr; // The second step, the last element of the array, is the current intermediate node int rootValue = postorder[postorder.size() - 1]; Node* t = new Node(rootValue); // Leaf Node if (postorder.size() == 1) return t; // Step 3, Find Cutting Point int delimiterIndex; for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) { if (inorder[delimiterIndex] == rootValue) break; } // Step 4, cut the middle order array to get the middle order left array and the middle order right array vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex); vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end()); // Step 5, Cut the post-ordinal array to get the post-ordinal left array and the post-ordinal right array postorder.resize(postorder.size() - 1); vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size()); vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end()); // Step 6 t->left = createBiTree(leftInorder, leftPostorder); t->right = createBiTree(rightInorder, rightPostorder); return t; } public: biTree() : root(nullptr) {} ~biTree() { delete[] root; } Node* getRoot() const { return root; } void createTree(vector<int>& inorder, vector<int>& postorder) { root = createBiTree(inorder, postorder); } void inOrder(Node* t, int sum) { if (t == nullptr) return; sum += t->data; inOrder(t->left, sum); cout << t->data << " " << sum << endl; inOrder(t->right, sum); } void setTree(Node* t, int& thePos) { if (t == nullptr) return; setTree(t->left, thePos); t->pos = thePos++; setTree(t->right, thePos); } void changeTree(Node* t, int pos, int theData) { if (t == nullptr) return; if (t->pos == pos) t->data = theData; else { changeTree(t->left, pos, theData); changeTree(t->right, pos, theData); } } }; int main() { int pos, newData; string str, op; while (getline(cin, str)) { vector<int> inorder; vector<int> postorder; biTree bitree; int len = str.length(); for (int i = 0; i < len; i++) { if (str[i] != ' ') { int key = 0; while (str[i] != ' ' && i < len) key = key * 10 + (str[i++] - '0'); inorder.push_back(key); } } getline(cin, str); len = str.length(); for (int i = 0; i < len; i++) { if (str[i] != ' ') { int key = 0; while (str[i] != ' ' && i < len) key = key * 10 + (str[i++] - '0'); postorder.push_back(key); } } bitree.createTree(inorder, postorder); Node* t = bitree.getRoot(); int pos = 1; bitree.setTree(t, pos); while (cin >> op && op != "STOP") { if (op == "UPDATE") { cin >> pos >> newData; bitree.changeTree(t, pos, newData); } else if (op == "QUERY") bitree.inOrder(t, 0); } getchar(); cout << endl; } return 0; }
summary
The first difficulty with this question is how to process multiple sets of data, so we can read a line of strings using getline.
Then the second difficulty is to create a binary tree based on the results of the middle and subsequent traversals. The general idea is to cut the last element bit of the subsequent ordinal array, cut the ordinal array first, then cut the ordinal array, and then the ordinal array, each time, the last element of the ordinal array is the current node element.
At first, I thought it would be a bit cumbersome to modify the weights of binary tree locations every time you UPDATAE. So I think, in this case, it's better to modify the middle and subsequent arrays each time you UPDATE, and then, when you encounter a QUERY operation, create a binary tree from the current middle and post-ordinal arrays, and then traverse the output in middle order. However, the sample passed, but the run error threw an exception terminate called after throwing an instance of'.
Since the school oj did not give complete anomaly information, this path is not accessible, so after you honestly create the tree, modify it on the basis of the original tree.
Since the weight of the specified pos is modified each time the UPDATE occurs, I add a pos member variable to the node to record that the current node is the first node to be sequentially traversed.