1. 程式人生 > >2019春季考試第4題 7-4 Structure of a Binary Tree (30 分)

2019春季考試第4題 7-4 Structure of a Binary Tree (30 分)

img node freopen root 遇到 題目 not 單詞 n)

題外話:考試的時候花了一個小時做了27分,由於Siblings這個單詞不知道意思,所以剩下的3分就沒去糾結了,後來發現單詞是兄弟的意思,氣哭~~

這道題的麻煩之處在於如何從一個字符串中去找數字。先首先我們需要整行讀取(包括空格),這個我自己寫另一個函數,挺好用的:

string mygets()
{
    char str[100];
    fgets(str,sizeof(str),stdin);
    int len = strlen(str);
    if(str[len-1]==\n) str[len-1] = \0;
    return str;
}

用的時候只要 string str = mygets();就可以了,裏面已經去掉換行符了。

下一步是再寫一個從istart位置讀取數字的函數,先從istart位置讀取字符串(遇到空格,讀取結束),然後用atoi把字符串轉換成數字。

//字符串中istart位置開始取某個單詞(以空格結束)
int getNum(string str,int istart)
{
    int len = str.length();
    string strA="";
    for(int i=istart;i<len;++i)
        if(str[i]== ) break
; else strA += str[i]; //printf("%s\n",strA.c_str()); int a = atoi(strA.c_str()); return a; }
題目中的字符串格式太多了是吧,眼花繚亂:
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
拿字符串
siblings舉例吧,想用find函數siblings字符串,如果返回不等於-1,表示就是此種類型,然後用以下代碼獲取數字8和2。註意find函數的用法,返回的是查找字符串的首地址,所以find "of"返回的是o出現的首地址,沒有找到of則返回-1,否則返回o的首地址。然後我們可以想象一下istart+1是f,istart+2是空格,istart+3就是我們所要的數字出現的首地址。
    if(str.find("siblings")!=-1)
    {
        int a = getNum(str,0);
        int b = getNum(str,str.find("of")+3);
    }

  以下是我的代碼:

PS:如果我的構樹代碼看不懂,可以看我寫的這篇文章讓你懂得已知先序(後序)與中序遍歷如何快速構樹:https://www.cnblogs.com/jlyg/p/10402919.html

樹的結構體中我加了level變量,記錄當前節點的水平深度。其他看代碼吧~~

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<cstring>
using namespace std;
struct Node{
    int val;
    int level;
    Node* left;
    Node* right;
    Node(){
        left = right = NULL;
        level = 0;
    }
};
map<int,int> valtoid;               //通過值去找id
map<int,Node*> valtonode;           //通過值去找節點
//構造數
Node* Insert(Node* node,int val)
{
    if(node==NULL)
    {
        node = new Node();
        node->val= val;
        valtonode[val] = node;
    }
    else if(valtoid[val] < valtoid[node->val])
    {
               node->left = Insert(node->left,val);
            node->left->level = node->level+1;
    }
    else
    {
        node->right= Insert(node->right,val);
        node->right->level = node->level+1;
    }
    return node;
}
Node* root = NULL;
int n;
//是不是滿二叉樹
bool isFullTree(Node* root)
{
    queue<Node*> q;
    q.push(root);
    Node* node;
    while(!q.empty())
    {
        node = q.front();
        q.pop();
        if(node->left)
            q.push(node->left);
        if(node->right)
            q.push(node->right);
        if(node->left&&!node->right || !node->left&&node->right)
            return false;
    }
    return true;
}
//字符串中istart位置開始取某個單詞(以空格結束)
int getNum(string str,int istart)
{
    int len = str.length();
    string strA="";
    for(int i=istart;i<len;++i)
        if(str[i]== ) break;
        else strA += str[i];
    //printf("%s\n",strA.c_str());
    int a = atoi(strA.c_str());
    return a;
}
//是不是兄弟節點
bool isSiblings(Node* node,Node* child1,Node* child2)
{
    if(node==NULL) return false;
    if(node->left==child1&&node->right!=child2||
       node->left==child2&&node->right!=child1) return false;
    else if(node->left==child1&&node->right==child2||
       node->left==child2&&node->right==child1) return true;
    return isSiblings(node->left,child1,child2)||isSiblings(node->right,child1,child2);
}
//判斷這一個這句話是不是對的
bool isRight(string str)
{

    if(str.find("root")!=-1)
    {
        int a = getNum(str,0);
        return a == root->val;
    }
    else if(str.find("siblings")!=-1)
    {
        int a = getNum(str,0);
        int b = getNum(str,str.find("of")+3);
        //兄弟節點,必須在同一層
        if(valtonode[b]&&valtonode[a]&&valtonode[b]->level==valtonode[a]->level)
        {
            if(isSiblings(root,valtonode[a],valtonode[b]))
                return true;
        }
        return false;
    }
    else if(str.find("parent")!=-1)
    {
        int a = getNum(str,0);
        int b = getNum(str,str.find("of")+3);
        if(valtonode[b]&&valtonode[a])
        {
            if(valtonode[a]->left == valtonode[b] || valtonode[a]->right == valtonode[b])
            return true;
        }
        return false;
    }
    else if(str.find("left")!=-1)
    {
        int a = getNum(str,0);
        int b = getNum(str,str.find("of")+3);
        if(valtonode[b]&&valtonode[a])
        {
            if(valtonode[b]->left==valtonode[a])
                return true;
        }
        return false;
    }
    else if(str.find("right")!=-1)
    {
        int a = getNum(str,0);
        int b = getNum(str,str.find("of")+3);
        if(valtonode[b]&&valtonode[a])
        {
            if(valtonode[b]->right==valtonode[a])
                return true;
        }
    }
    else if(str.find("same")!=-1)
    {
        int a = getNum(str,0);
        int b = getNum(str,str.find("and")+4);
        if(valtonode[b]&&valtonode[a])
        {
            if(valtonode[b]->level==valtonode[a]->level)
                return true;
        }
        return false;
    }
    else if(str.find("full")!=-1)
    {
        return isFullTree(root);
    }
    return false;
}
string mygets()
{
    char str[100];
    fgets(str,sizeof(str),stdin);
    int len = strlen(str);
    if(str[len-1]==\n) str[len-1] = \0;
    return str;
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.txt","r",stdin);
    #endif
    scanf("%d",&n);
    int post[n];
    for(int i=0;i<n;++i)
        scanf("%d",&post[i]);
    for(int i=0;i<n;++i)
    {
        int a;
        scanf("%d",&a);
        valtoid[a] = i;
    }
    for(int i=n-1;i>=0;--i)
        root = Insert(root,post[i]);
    int m;
    scanf("%d",&m);
    getchar();
    for(int i=0;i<m;++i)
    {
        string str = mygets();
        bool bRight = isRight(str);
        printf("%s\n",bRight?"Yes":"No");
    }
    return 0;
}
View Code

題目在下面:

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.

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:

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.

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

 

2019春季考試第4題 7-4 Structure of a Binary Tree (30 分)