• 百练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
    #include <cstdio>
    #include <stack>
    #include <queue>
    using namespace std;
    struct node{
        char x;
        node *lchild;
        node *rchild;
    }tree[1002];
    int loc,n;
    char temp[3];
    node* create(){     //生成一个新的结点,并将其孩子结点置为NULL
            tree[loc].lchild = NULL;
            tree[loc].rchild = NULL;
            return &tree[loc++];
    }
    node *build(){      //该题输入为伪满二叉树的前序遍历,利用0、1标志来识别外结点和内结点
        scanf("%s",temp);
        node *p = create();
        p->x = temp[0];
        if(temp[1] == '0' && p->x != '$'){
        //if(loc != n)    //因为已经给出01标志了,并且是伪满二叉树,所以这道题目的n(树的结点个数)信息冗余。
            p->lchild = build();
        //if(loc != n)
            p->rchild = build();
        }
        return p;
    }
    void Print(node *p){ //输出该树的镜像翻转
        stack<node *> s;
        queue<node *>Q;
        while(p != NULL){   //此处是关键,根据“左孩子右兄弟”的特点,一直向右遍历,将树同一层的结点都放在栈内
            //printf("push:%c.",p->x);
            if(p->x != '$')
            s.push(p);
            p = p->rchild;
        }
        while(!s.empty()){  //将栈内的结点依次弹出,压入队列,完成镜像翻转的功能
            Q.push(s.top());
            s.pop();
        }
        while(!Q.empty()){
            p = Q.front();
            Q.pop();
            printf("%c ",p->x);
            if(p->lchild != NULL){
                p = p->lchild;
                while(p != NULL){   //同理,上面是处理根节点的,因为那时队列还为空,这里是处理剩下的全部结点
                    //printf("push:%c
    ",p->x);
                    if(p->x != '$')
                        s.push(p);
                    p = p->rchild;
                }
                while(!s.empty()){
                    Q.push(s.top());
                    s.pop();
                }
            }
        }
        return;
    }
    void BFS(node *p){  //测试用的,实际上没调用
        queue<node *> Q;
        Q.push(p);
        while(!Q.empty()){
            p = Q.front();
            Q.pop();
            printf("%c ",p->x);
            if(p->lchild != NULL)
            Q.push(p->lchild);
            if(p->rchild != NULL)
            Q.push(p->rchild);
        }
    }
    
    int main(){
        loc = 0;
        scanf("%d",&n);
        node *root;
        root = build();
        Print(root);
        return 0;
    }

     

  • 相关阅读:
    一步步介绍如何给项目添加单元测试
    日期格式化在移动端的问题
    使用VW时,图片的问题
    转:vw适配中使用伪类选择器遇到的问题
    ES6模块的import和export用法总结
    转:如何在Vue项目中使用vw实现移动端适配
    PhpStrom添加调试功能
    小程序商城笔记
    使用TortoiseGit对android studio工程进行代码版本控制
    Android Studio 常见异常解决办法
  • 原文地址:https://www.cnblogs.com/starryxsky/p/7106710.html
Copyright © 2020-2023  润新知