Binary Tree Medium-Postorder Traversal and Operation Solutions

subject

Title Description

A binary tree is given by traversing in middle and after order, and now the following is done:

  1. 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

  2. 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

  3. 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.

Tags: C++

Posted on Sun, 07 Nov 2021 12:04:05 -0500 by corcode