题目链接
题目分析
输入顺序即为结点下标,输入内容为结点的左右子树下标
解题思路
1、保存输入结点信息
2、找到根结点(开一个bool
数组,看哪个结点没有作为子节点出现)
3、构造出二叉树
4、不用再invert
,遍历时反转顺序即可!
后记: 其实不用建树,结点保存在数组中,就相当于静态存储,直接可以遍历!
AC程序(C++)
/**************************
*@Author: 3stone
*@ACM: PAT.A1102 Invert a Binary Tree
*@Time: 18/7/26
*@IDE: VSCode 2018 + clang
***************************/
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct tree_key{
int lkey, rkey;
}key[20];
struct Node {
Node* lchild;
Node* rchild;
int data;
};
//构造二叉树
Node* create(int k) {
//递归基 无左右子树
if(k == -1)
return NULL;
Node* root = new Node;
root->data = k;
root->lchild = create(key[k].lkey);
root->rchild = create(key[k].rkey);
return root;
}//create
//中序遍历(左右子树反向)
void in_traversal(Node* root, int& n) {
if(root == NULL) return; //递归结束
in_traversal(root->rchild, n);
n--;
if(n == 0) printf("%d\n", root->data);
else printf("%d ", root->data);
in_traversal(root->lchild, n);
}//in-traversal
//层序遍历(左右子树反向)
void bfs_traversal(Node* root, int n) {
queue<Node*> que;
que.push(root);
while(!que.empty()) {
Node* p = que.front();
n--;
que.pop();
if(n == 0) printf("%d\n", p->data);
else printf("%d ", p->data);
if(p->rchild) que.push(p->rchild);
if(p->lchild) que.push(p->lchild);
}
}//bfs-traversal
int main() {
int n;
char left, right;
while(scanf("%d", &n) != EOF) {
bool flag[20]; //标记结点是否出现
int root_key; //记录根节点下标
memset(flag, false, sizeof(flag));
for(int i = 0; i < 20; i++){
key[i].lkey = -1;
key[i].rkey = -1;
}
for(int i = 0; i < n; i++) {
getchar(); //吸收换行符
scanf("%c %c", &left, &right);
//也可以这样吸收换行符:scanf("%*c%c %c", &left, &right);
if(left != '-') {
key[i].lkey = left - '0';
flag[left-'0'] = true;
}
if(right != '-') {
key[i].rkey = right - '0';
flag[right-'0'] = true;
}
}
//找到根节点下标
for(int i = 0; i < n; i++){
if(!flag[i])
root_key = i;
}
//建树
Node* root = create(root_key);
//层序遍历
bfs_traversal(root, n);
//中序遍历
in_traversal(root, n);
}//while
return 0;
}
来源:CSDN
作者:3stone_
链接:https://blog.csdn.net/qq_26398495/article/details/81229678