1. 程式人生 > >百練4082:樹的鏡面映射

百練4082:樹的鏡面映射

content front light 利用 內存 create true nod namespace

總時間限制: 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:樹的鏡面映射