题目:http://bailian.openjudge.cn/practice/4082
4082:树的镜面映射
总时间限制:
1000ms
内存限制:
65536kB
描述
一棵树的镜面映射指的是对于树中的每个结点,都将其子结点反序。例如,对左边的树,镜面映射后变成右边这棵树。
a a
/ | \ / | \
b c f ===> f c b
/ \ / \
d e e d
我们在输入输出一棵树的时候,常常会把树转换成对应的二叉树,而且对该二叉树中只有单个子结点的分支结点补充一个虚子结点“$”,形成“伪满二叉树”。
例如,对下图左边的树,得到下图右边的伪满二叉树
a a
/ | \ / \
b c f ===> b $
/ \ / \
d e $ c
/ \
d f
/ \
$ e
然后对这棵二叉树进行前序遍历,如果是内部结点则标记为0,如果是叶结点则标记为1,而且虚结点也输出。
现在我们将一棵树以“伪满二叉树”的形式输入,要求输出这棵树的镜面映射的宽度优先遍历序列。
输入
输入包含一棵树所形成的“伪满二叉树”的前序遍历。
第一行包含一个整数,表示结点的数目。
第二行包含所有结点。每个结点用两个字符表示,第一个字符表示结点的编号,第二个字符表示该结点为内部结点还是外部结点,内部结点为0,外部结点为1。结点之间用一个空格隔开。
数据保证所有结点的编号都为一个小写字母。
输出
输出包含这棵树的镜面映射的宽度优先遍历序列,只需要输出每个结点的编号,编号之间用一个空格隔开。
样例输入
9
a0 b0 $1 c0 d0 $1 e1 f1 $1
样例输出
a f c b e d
提示
样例输入输出对应着题目描述中的那棵树
AC代码:
关于建树的部分,不是很懂
参考的别人的代码;
疑问点:
题1:https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=40&tqId=21342&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking
题2:
http://bailian.openjudge.cn/practice/4082
这两个题的前序建树部分条件有啥不同?
答:
题1的前序建树的部分是给出了所有的空结点
题2 对该二叉树中只有单个子结点的分支结点补充一个虚子结点“$”,形成“伪满二叉树”。
就是只补充了单个子结点的分支
AC代码:
#include <iostream>
#include <string>
#include <stack>
#include <queue>
#include <string.h>
using namespace std;
//输入二叉树前序遍历
//输出还原的树的bfs遍历的结果
struct Node{
char v;
Node *left;
Node *right;
}tree[200];
int loc=0,idx=0;
int len;
char str[200];
int tag[200];
Node *create(char c){
tree[loc].left=tree[loc].right=NULL;
tree[loc].v=c;
return &tree[loc++];
}
//根据前序遍历建树
Node *buildBypre(Node *T){
if(idx>=len)
return NULL;
char ct=str[idx]; //idx是全局变量
int tg=tag[idx++];
if(ct=='$')
return NULL;
T=create(ct);
if(tg==0 && ct!='$'){
T->left=buildBypre(T->left);
T->right=buildBypre(T->right);
}
return T;
}
void printBFS(Node *root){
//左儿子 右兄弟
cout<<root->v<<" ";
stack<Node *> stack1;
queue<Node *> queue1;
if(root->left!=NULL)
queue1.push(root);
while(!stack1.empty() || !queue1.empty()){
Node *tt=queue1.front();
queue1.pop();
tt=tt->left;
stack1.push(tt);
tt=tt->right;
while(tt!=NULL){
stack1.push(tt);
tt=tt->right;
}
while(!stack1.empty()){
cout<<stack1.top()->v<<" ";
if(stack1.top()->left!=NULL){
queue1.push(stack1.top()); //她的左儿子不为空
}
stack1.pop();
}
}
}
int main(){
char c;
int n,t;
loc=idx=0;
cin>>n;
int i=0;
for(;i<n;i++){
cin>>c>>t;
str[i]=c;
tag[i]=t;
}
str[i]='\0'; //这样加字符串比较保险
len=strlen(str);
Node *r=buildBypre(NULL); //根据前序遍历建树
//输出这棵二叉树对应树 的镜面映射的宽度优先遍历序列
printBFS(r);
return 0;
}