【算法练习】数据结构/二叉树 前序重建 以及 树与二叉树转换4082:树的镜面映射

题目: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_40760678/article/details/100180900