PAT(甲級)2019年春季考試 7-4 Structure of a Binary Tree

7-4 Structure of a Binary Tree (30分)

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, a binary tree can be uniquely determined.node

Now given a sequence of statements about the structure of the resulting tree, you are supposed to tell if they are correct or not. A statment is one of the following:ios

  • A is the root
  • A and B are siblings
  • A is the parent of B
  • A is the left child of B
  • A is the right child of B
  • A and B are on the same level
  • It is a full tree

Note:算法

  • Two nodes are on the same level, means that they have the same depth.
  • A full binary tree is a tree in which every node other than the leaves has two children.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer $N (≤30)$, the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are no more than $10​^3$​​ and are separated by a space.數組

Then another positive integer $M (≤30)$ is given, followed by M lines of statements. It is guaranteed that both A and B in the statements are in the tree.post

Output Specification:

For each statement, print in a line Yes if it is correct, or No if not.測試

Sample Input:

9
16 7 11 32 28 2 23 8 15
16 23 7 32 11 2 28 15 8
7
15 is the root
8 and 2 are siblings
32 is the parent of 11
23 is the left child of 16
28 is the right child of 2
7 and 11 are on the same level
It is a full tree

Sample Output:

Yes
No
Yes
No
Yes
Yes
Yes

題目限制:

image.png

題目大意:

給定一顆二叉樹的中序和後序,現有7種不一樣的查詢語句,若是該語句描述正確,輸出Yes,不然輸出No。spa

算法思路:

這裏給出2種不一樣的實現方式,一種是先建樹,而後使用BFS記錄該樹的信息(比較好想到),第二種是在建樹的過程當中直接記錄所須要的全部信息。
首先給出7種查詢,該如何判斷是否正確的方法:code

  • A is the root(直接判斷後序序列最後一個節點是否和A相等便可)
  • A and B are siblings(使用parent數組記錄全部的節點的父親,只要判斷parent[A]是否和parent[B]相等便可)
  • A is the parent of B(判斷parent[B]是否和A相等便可)
  • A is the left child of B(使用leftChild數組記錄全部節點惡左孩子,判斷leftChild[B]與A是否相等便可)
  • A is the right child of B(使用rightChild數組記錄全部節點惡左孩子,判斷rightChild[B]與A是否相等便可)
  • A and B are on the same level(使用level數組記錄全部節點的層次,而後判斷level[A]和level[B]是否相等便可)
  • It is a full tree(使用isFullTree記錄該樹是否存在只有一個孩子的狀況,若是是說明不是full tree,不然就是)
先建樹,而後使用BFS獲取信息:
Node* createTree(int postL,int postR,int inL,int inR){
    if(postL>postR) return nullptr;
    Node *root = new Node;
    root->data = post[postR];
    int k = pos[post[postR]];// 根節點位置
    int numOfLeft = k-inL;
    root->left = createTree(postL,postL+numOfLeft-1,inL,k-1);
    root->right = createTree(postL+numOfLeft,postR-1,k+1,inR);
    return root;
}

void BFS(Node *root,bool &isFullTree){
    queue<Node*> q;
    root->level = 1;
    parent[root->data] = -1;
    level[root->data] = 1;
    q.push(root);
    while (!q.empty()){
        Node *t = q.front();
        q.pop();
        if((t->left||t->right)&&!(t->left&&t->right)){
            isFullTree = false;
        }
        if(t->left!= nullptr){
            t->left->level = t->level+1;
            parent[t->left->data] = t->data;
            level[t->left->data] = t->level+1;
            leftChild[t->data] = t->left->data;
            q.push(t->left);
        }
        if(t->right!= nullptr){
            t->right->level = t->level+1;
            level[t->right->data] = t->level+1;
            parent[t->right->data] = t->data;
            rightChild[t->data] = t->right->data;
            q.push(t->right);
        }
    }
}
在建樹的時候獲取信息:
bool isFullTree = true;
Node* createTree(int postL,int postR,int inL,int inR,int depth,int pa){
    if(postL>postR) return nullptr;
    Node *root = new Node;
    root->data = post[postR];
    parent[root->data] = pa;
    level[root->data] = depth;
    int k = pos[post[postR]];// 根節點位置
    int numOfLeft = k-inL;
    root->left = createTree(postL,postL+numOfLeft-1,inL,k-1,depth+1,root->data);
    root->right = createTree(postL+numOfLeft,postR-1,k+1,inR,depth+1,root->data);
    leftChild[root->data] = root->left?post[postL+numOfLeft-1]:-1;
    rightChild[root->data] = root->right?post[postR-1]:-1;
    if((root->left||root->right)&&!(root->left&&root->right)){
        isFullTree = false;
    }
    return root;
}
將輸入的字符串根據空格劃分爲字符串數組:
string query;
getline(cin,query);
vector<string> all;
string r;
for(char i : query){
    if(i==' '){
        all.push_back(r);
        r = "";
    } else{
        r += i;
    }
}
all.push_back(r);

注意點:

  • 一、在判斷類型的時候,最好是先判斷長度,再判斷關鍵字,否則測試點1和測試點4會出現運行時錯誤。尤爲是在判斷A and B are on the same level類型的時候。
  • 二、在使用getline第一次輸入的時候須要先使用getchar()接收回車。

提交結果:

image.png

AC代碼1(一遍建樹一遍獲取信息):

#include<cstdio>
#include <string>
#include <vector>
#include <iostream>

using namespace std;
/*
 * 題目大意:
 *
 */
struct Node{
    int data;
    Node* left;
    Node* right;
};

int N;
int in[40],post[40],pos[1005],parent[1005],leftChild[1005],rightChild[1005],level[1005];
bool isFullTree = true;
Node* createTree(int postL,int postR,int inL,int inR,int depth,int pa){
    if(postL>postR) return nullptr;
    Node *root = new Node;
    root->data = post[postR];
    parent[root->data] = pa;
    level[root->data] = depth;
    int k = pos[post[postR]];// 根節點位置
    int numOfLeft = k-inL;
    root->left = createTree(postL,postL+numOfLeft-1,inL,k-1,depth+1,root->data);
    root->right = createTree(postL+numOfLeft,postR-1,k+1,inR,depth+1,root->data);
    leftChild[root->data] = root->left?post[postL+numOfLeft-1]:-1;
    rightChild[root->data] = root->right?post[postR-1]:-1;
    if((root->left||root->right)&&!(root->left&&root->right)){
        isFullTree = false;
    }
    return root;
}

int main(){
    scanf("%d",&N);
    for (int i = 0; i < N; ++i) {
        scanf("%d",&post[i]);
    }
    for (int i = 0; i < N; ++i) {
        scanf("%d",&in[i]);
        pos[in[i]] = i;
    }
    Node *root = createTree(0,N-1,0,N-1,1,-1);
    int M;
    scanf("%d",&M);
    getchar();
    for (int j = 0; j < M; ++j) {
        string query;
        getline(cin,query);
        vector<string> all;
        string r;
        for(char i : query){
            if(i==' '){
                all.push_back(r);
                r = "";
            } else{
                r += i;
            }
        }
        all.push_back(r);
        if(all[3]=="root"){
            if(root->data==stoi(all[0])){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all[4]=="siblings"){
            int a = stoi(all[0]);
            int b = stoi(all[2]);
            if(parent[a]==parent[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all[3]=="parent"){
            int a = stoi(all[0]);
            int b = stoi(all[5]);
            if(a==parent[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all[3]=="left"){
            int a = stoi(all[0]);
            int b = stoi(all[6]);
            if(a==leftChild[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        }else if(all[3]=="right"){
            int a = stoi(all[0]);
            int b = stoi(all[6]);
            if(a==rightChild[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all.size()==8){
            int a = stoi(all[0]);
            int b = stoi(all[2]);
            if(level[a]==level[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else{
            if(isFullTree){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        }
    }
    return 0;
}

AC代碼2(先建樹後BFS):

#include<cstdio>
#include <string>
#include <cmath>
#include <set>
#include <vector>
#include <queue>
#include <iostream>

using namespace std;

struct Node{
    int data;
    Node* left;
    Node* right;
    int level;
};

int N;
int in[40],post[40],pos[1005],parent[1005],leftChild[1005],rightChild[1005],level[1005];

Node* createTree(int postL,int postR,int inL,int inR){
    if(postL>postR) return nullptr;
    Node *root = new Node;
    root->data = post[postR];
    int k = pos[post[postR]];// 根節點位置
    int numOfLeft = k-inL;
    root->left = createTree(postL,postL+numOfLeft-1,inL,k-1);
    root->right = createTree(postL+numOfLeft,postR-1,k+1,inR);
    return root;
}

void BFS(Node *root,bool &isFullTree){
    queue<Node*> q;
    root->level = 1;
    parent[root->data] = -1;
    level[root->data] = 1;
    q.push(root);
    while (!q.empty()){
        Node *t = q.front();
        q.pop();
        if((t->left||t->right)&&!(t->left&&t->right)){
            isFullTree = false;
        }
        if(t->left!= nullptr){
            t->left->level = t->level+1;
            parent[t->left->data] = t->data;
            level[t->left->data] = t->level+1;
            leftChild[t->data] = t->left->data;
            q.push(t->left);
        }
        if(t->right!= nullptr){
            t->right->level = t->level+1;
            level[t->right->data] = t->level+1;
            parent[t->right->data] = t->data;
            rightChild[t->data] = t->right->data;
            q.push(t->right);
        }
    }
}

int main(){
    scanf("%d",&N);
    for (int i = 0; i < N; ++i) {
        scanf("%d",&post[i]);
    }
    for (int i = 0; i < N; ++i) {
        scanf("%d",&in[i]);
        pos[in[i]] = i;
    }
    Node *root = createTree(0,N-1,0,N-1);
    bool isFullTree = true;
    BFS(root,isFullTree);
    int M;
    scanf("%d",&M);
    for (int j = 0; j < M; ++j) {
        string query;
        if(j==0){
            // 要吸取第一個回車
            getchar();
        }
        getline(cin,query);
        vector<string> all;
        string r;
        for(char i : query){
            if(i==' '){
                all.push_back(r);
                r = "";
            } else{
                r += i;
            }
        }
        all.push_back(r);
        if(all[3]=="root"){
            if(root->data==stoi(all[0])){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all[4]=="siblings"){
            int a = stoi(all[0]);
            int b = stoi(all[2]);
            if(parent[a]==parent[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all[3]=="parent"){
            int a = stoi(all[0]);
            int b = stoi(all[5]);
            if(a==parent[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all[3]=="left"){
            int a = stoi(all[0]);
            int b = stoi(all[6]);
            if(a==leftChild[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        }else if(all[3]=="right"){
            int a = stoi(all[0]);
            int b = stoi(all[6]);
            if(a==rightChild[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else if(all.size()==8){
            int a = stoi(all[0]);
            int b = stoi(all[2]);
            if(level[a]==level[b]){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        } else{
            if(isFullTree){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        }
    }
    return 0;
}
相關文章
相關標籤/搜索