More answers to PAT class a questions – acking-you.github.io
subject
Topic analysis
Main idea of the title:
Binary search tree is no stranger to everyone. This problem requires you to construct a binary tree. The binary search tree is also a complete binary tree, and then print out its sequence traversal sequence.
- This question got me into trouble. What I thought for the first time was not to reconstruct this binary tree from its middle order. What I began to think was very complicated 🤣
Firstly, according to the properties of binary search tree, we can know its middle order traversal sequence (directly arrange an order). In fact, when we know the middle order traversal sequence, we can construct the corresponding complete binary tree. According to the middle order, we can use recursive reverse derivation.
However, what I thought of for the first time was to find out the number of layers of the complete binary tree, and then find out the number of left subtrees of the complete binary tree according to this, and then we can get the root node of the complete binary tree (because it is orderly and the left side of the root node is less than the number of root nodes, we can get the number of root nodes directly according to the number of left subtree nodes), I just want to find out the total root and then take it to build a complete binary tree. I don't know what I give you is a complete binary tree. I just need to build it directly according to the middle order!
Look at my error code 🤣 (the actual data volume is not large enough)
#include <bits/stdc++.h> using namespace std; int N; int* nums; int* res; int left_sum; void pre_handle() { //Because it is a complete binary tree, if the number of layers is I, there are 2 ^ (i-1) - 1 < = n < = 2 ^ I-1 int i = 1; while ((1 << i) - 1 < N)i++; int leave = N - (1 << (i - 1)) + 1 > (1 << (i - 1)) / 2 ? (1 << (i - 1)) / 2 : N - (1 << (i - 1)) + 1; //Judge whether it is half full. If it is greater than half full, the mantissa of the left subtree is half full left_sum = leave + ((1 << (i - 1)) - 2) / 2; //Get the total number of left subtrees } void Input() { ios::sync_with_stdio(false); cin >> N; nums = new int[N]; res = new int[N]; for (int i = 0; i < N; i++) { cin >> nums[i]; } sort(nums, nums + N); pre_handle(); } void BST(int root, int l, int r) { if (l > r) return ; int t_l = l, t_r = r, node; if (root == 0) { node = l + left_sum; } else node = (t_l + t_r) % 2 == 0 ? (t_l + t_r) / 2 : (t_l + t_r) / 2 + 1; res[root] = nums[node]; BST(root * 2 + 1, l, node - 1); BST(root * 2 + 2, node + 1, r); } void print() { BST(0, 0, N - 1); for (int i = 0; i < N; i++) { if (i != N - 1) cout << res[i] << ' '; else { cout << res[i]; } } } int main() { Input(); print(); return 0; }
Correct code explanation
In fact, as long as we understand the middle order traversal deeply enough, we can basically count seconds.
Because the sorted data is the middle order traversal, and the middle order traversal is left root right, we also need to be left root right when we rebuild the complete binary tree. For the complete binary tree starting from the array subscript 0, the left subtree is i*2+1 and the right subtree is i*2+2. Because the subtrees are abstract data and the roots are concrete, they need to be repeated The complete binary tree is assigned a value until the root is obtained.
- After storing the sequence of complete binary tree with array, its sequence is the sequence of sequence traversal... So it can be printed directly
#include <bits/stdc++.h> using namespace std; int N; int* nums; int* res; int idx = 0; void Input() { ios::sync_with_stdio(false); cin >> N; nums = new int[N]; res = new int[N]; for (int i = 0; i < N; i++) { cin >> nums[i]; } sort(nums, nums + N); } void creatCBT(int root) { if (root >= N) return; creatCBT(root * 2 + 1); //Left subtree res[root] = nums[idx++];//root creatCBT(root * 2 + 2); //Right subtree } void print() { creatCBT(0); for (int i = 0; i < N; i++) { cout << res[i] << ' '; } } int main() { Input(); print(); return 0; }