- 题目
- 题目解析
- 正确代码详解
更多PAT甲级题解– acking-you.github.io 题目
OJ平台
题目大意:
二叉搜索树大家都不陌生,这个题需要你构造的二叉树二叉搜索树同时也是完全二叉树,然后打印出它的层序遍历序列。
- 这道题把我坑到了,我竟第一时间想的并不是从它的中序重新构建出这颗二叉树,我开始想的非常复杂藍
首先根据二叉搜索树的性质可知它的中序遍历序列(直接排个序),实际上知道了中序遍历序列就已经可以构造出对应的完全二叉树了,根据中序利用递归反向推导即可。
然而我却第一时间想到的是先求出这颗完全二叉树的层数,然后根据这个求出这颗完全二叉树左子树的个数,然后便可以得出这颗完全二叉树的根结点(由于有序,且根结点的左边都是小于根结点的数,所以直接根据左子树结点个数可得出根节点的编号),我一心只想着求出这个总根之后再取构建完全二叉树,熟不知给你的本就是一棵完全二叉树,只需要根据中序直接构建即可!
看看我这错误代码藍(实际数据量不大都能过
#include正确代码详解using namespace std; int N; int* nums; int* res; int left_sum; void pre_handle() { //由于是完全二叉树,所以设层数为i则有,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; //判断是否半满,如果大于半满则左子树的尾数为半满个数 left_sum = leave + ((1 << (i - 1)) - 2) / 2; //得出左子树总个数 } 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; }
实际上我们只要对中序遍历理解的够深,基本就能秒了。
由于我们经过排序后的数据就是中序遍历,而中序遍历都是 左-根-右 ,所以在我们重新构建完全二叉树的时候也需要是 左-根-右 ,对于从数组下标0开始的完全二叉树,有左子树为 i*2+1 ,右子树为 i*2+2 。由于子树都是抽象的数据,根则是具体的,所以需要不断递归直到得到根就开始给完全二叉树赋值。
- 由于用数组存下完全二叉树的序列后,它的序列就是层序遍历的序列。。。所以直接打印即可
#includeusing 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); //左子树 res[root] = nums[idx++];//根 creatCBT(root * 2 + 2); //右子树 } void print() { creatCBT(0); for (int i = 0; i < N; i++) { cout << res[i] << ' '; } } int main() { Input(); print(); return 0; }



