7-3 树的同构(25 分)

给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。
//示例图略
现给定两棵树,请你判断它们是否是同构的。

输入格式:>
输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N
(≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。

输出格式:>
如果两棵树是同构的,输出“Yes”,否则输出“No”。
输入样例1:
8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

输出样例1: Yes

输入样例2:
8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4

输出样例2: No

根据输入格式,可以想到树的建立可以使用一个结构体数组表示。再由树的特征,因为题意要判断树是否相同,是通过某两个内容一致的节点的特征是否一致来判断的,这里就不一定需要知道用数组表示的树的树根在哪里。

#include<stdio.h>
#include<stdlib.h>

typedef struct Tree *BT;
struct Tree
{
    int left;
    int right;
    char data;
};

BT writeTree(int);
int isLikeTree(BT, int, BT, int);

int main(void)
{
    int N, M;
    BT T1, T2;

    scanf("%d", &N);
    getchar();
    T1 = writeTree(N);

    scanf("%d", &M);
    getchar();
    T2 = writeTree(M);

    if(isLikeTree(T1, N, T2, M) == 0)
        puts("Yes");
    else
        puts("No");

    free(T1);
    free(T2);

    return 0;
}

//建树并输入树的信息,输入按字符
BT writeTree(int n)
{
    int count;
    char cl, cr;
    BT BitTree;

    BitTree = (BT)calloc(n, sizeof(struct Tree));

    for(count = 0; count < n; count++)
    {
        BitTree[count].data = getchar();
        getchar();
        cl = getchar();
        getchar();
        cr = getchar();
        getchar();

        if(cl >= '0' && cl <= '9')
        {
            BitTree[count].left = cl - '0';
        }
        else
        {
            BitTree[count].left = -1;
        }

        if(cr >= '0' && cr <= '9')
        {
            BitTree[count].right = cr - '0';
        }
        else
        {
            BitTree[count].right = -1;
        }
    }

    return BitTree;
}

/*传入树1根、树1节点数,树2根、树2节点数。
是同一棵树时返回0*/
int isLikeTree(BT Tree1, int N, BT Tree2, int M)
{
    int cnt1, cnt2;
    int JUG = 0;

    if(N != M)
        return 1;

    if(N == 1 && M == 1 )
    {
        if(Tree1[cnt1].data - Tree2[cnt2].data)
            return 1;
    }
    //搜索两树的每一个节点
    for(cnt1 = 0; cnt1 < N; cnt1++)
    {
        for(cnt2 = 0; cnt2 < M; cnt2++)
        {
            if(Tree1[cnt1].data - Tree2[cnt2].data == 0) //比较节点值相同的节点
            {
                if(Tree1[cnt1].left == -1 && Tree2[cnt2].left == -1
                && Tree1[cnt1].right == -1 && Tree2[cnt2].right == -1) //遇到同为叶节点
                   {
                       break;
                   }

                else if( (Tree1[cnt1].left == -1 && Tree1[cnt1].right == -1)
                      && (Tree2[cnt2].right != Tree2[cnt2].left) ) //树1叶节点,对应到树2有子节点
                {
                    JUG++;
                    break;
                }

                else if( (Tree1[cnt1].left != Tree1[cnt1].right)
                      && (Tree2[cnt2].right == -1 && Tree2[cnt2].left == -1) ) //树1节点有子节点,对应树2叶节点
                {
                    JUG++;
                    break;
                }

                else if( (Tree1[cnt1].left == -1 || Tree1[cnt1].right == -1)
                      && (Tree2[cnt2].right != -1 && Tree2[cnt2].left != -1) ) //树1单边子,树2叶节点
                {
                    JUG++;
                    break;
                }

                else if( (Tree2[cnt2].left == -1 || Tree2[cnt2].right == -1)
                      && (Tree1[cnt1].right != -1 && Tree1[cnt1].left != -1) ) //树2单边子,树1叶节点
                {
                    JUG++;
                    break;
                }

                else
                {
                    if( ( (Tree1[Tree1[cnt1].left].data != Tree2[Tree2[cnt2].left].data)
                            && (Tree1[Tree1[cnt1].right].data != Tree2[Tree2[cnt2].right].data) )
                            &&
                             ( (Tree1[Tree1[cnt1].right].data != Tree2[Tree2[cnt2].left].data)
                            && (Tree1[Tree1[cnt1].left].data != Tree2[Tree2[cnt2].right].data) ) ) //两树节点的子节点都对不上
                    {
                        JUG++;
                    }

                    break;
                }
            }//if(Tree1[cnt1].data - Tree2[cnt2].data == 0)
        }//for(cnt2 = 0; cnt2 < M; cnt2++)
    }//for(cnt1 = 0; cnt1 < N; cnt1++)

    return JUG;
}

猜你喜欢

转载自blog.csdn.net/asura319/article/details/78837439