码迷,mamicode.com
首页 > 其他好文 > 详细

百练4082:树的镜面映射

时间:2017-07-02 19:04:04      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:std   inline   优先   highlight   ++   log   problem   编号   root   

总时间限制:  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\n",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;
}

 

 

百练4082:树的镜面映射

标签:std   inline   优先   highlight   ++   log   problem   编号   root   

原文地址:http://www.cnblogs.com/starryxsky/p/7106710.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!