0
点赞
收藏
分享

微信扫一扫

树的同构


给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。



树的同构_结点


图1

树的同构_#include_02

图2


现给定两棵树,请你判断它们是否是同构的。

输入格式:

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

输出格式:

如果两棵树是同构的,输出“Yes”,否则输出“No”。

输入样例1(对应图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(对应图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


方法一用链式解决,刚开始学的时候用的能够AC, 然后复习的时候发现 方法二 用数组也能做, 未能提交,但是过了样例,如下。


方法一 :


#include<stdlib.h>
#include <string.h>
#include<stdio.h>
#include<malloc.h>
#define TRUE       1
#define FALSE      0
#define OK         1
#define ERROR      0
#define OVERFLOW   -1
#define INFEASIBLE -2
#define NULL  0
int n1 = 0, n2 = 0;
typedef int Status;
typedef char TElemType;
typedef struct BiTNode
{
   TElemType data;
   int left, right;
   struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
void ConnectBiTreeLeft(BiTNode *root, BiTNode T[])
{
     if(root->left != -1)
     {
        root->lchild = &T[root->left];
        ConnectBiTreeLeft(root->lchild, T);
     }
     else
        return;
}
void ConnectBiTreeRight(BiTNode *root, BiTNode T[])
{
     if(root->right != -1)
     {
        root->rchild = &T[root->right];
        ConnectBiTreeRight(root->rchild, T);
     }
     else
        return;
}
BiTree SearchRoot(BiTNode a[], int n)
{
    int temp[15] = {0};
    for(int i = 0; i < n; ++i)
    {
        if(a[i].left != -1)
          temp[a[i].left] = 1;
        if(a[i].right != -1)
          temp[a[i].right] = 1;
    }
    for(int i = 0; i < n; ++i)
       if(temp[i] == 0)
        return &a[i];
}
void InPut(BiTNode Node[], int n)
{
    char l, r;
    //printf("InPut****************n = %d\n", n);
    for(int i = 0; i < n; ++i)
    {
        getchar();
        scanf("%c %c %c", &Node[i].data, &l, &r);
       // printf("InPut%c %c %c\n", Node[i].data, l, r);
        if(l != '-')
            Node[i].left = l - '0';
        else
            {
              Node[i].left = -1;
              Node[i].lchild = NULL;
            }
        if(r != '-')
            Node[i].right = r - '0';
        else
             {
              Node[i].right = -1;
              Node[i].rchild = NULL;
            }
    }
    //printf("InPut****************\n");
}
Status PreOrderTraverse(BiTree T, Status (*visit)(char))
{
    if(T)
    {
        if((*visit)(T->data))
            if(PreOrderTraverse(T->lchild, (*visit)))
              if(PreOrderTraverse(T->rchild, (*visit)))
                return OK;
        else
            return ERROR;

    }
    else
        return OK;

}

Status Print(char e)
{
    printf("%c", e);
    return OK;

}
Status Compare(BiTree T1, BiTree T2)
{
    if(T1 == NULL || T2 == NULL)
        return T1 == T2;
    if(T1->data == T2->data)
    {
       return (Compare(T1->lchild, T2->lchild) && Compare(T1->rchild, T2->rchild)) || (Compare(T1->lchild, T2->rchild) && Compare(T1->rchild, T2->lchild));
    }
    return FALSE;

}
int main()
{
    BiTree T1 = NULL, T2 = NULL;
    BiTNode a1[15], a2[15];
    char b1[15], b2[15];
    int n1, n2;
    scanf("%d", &n1);
    InPut(a1, n1);
    scanf("%d", &n2);
    InPut(a2, n2);
   // printf("0****************\n");
    if(n1 != n2)
    {
       printf("No");
       return 0;
    }
    else
    {
       // printf("1****************\n");
       for(int i = 0; i < n1; ++i)
       {
         // printf("2****************\n");
           ConnectBiTreeLeft(&a1[i], a1);
           ConnectBiTreeRight(&a1[i], a1);
           ConnectBiTreeLeft(&a2[i], a2);
           ConnectBiTreeRight(&a2[i], a2);
       }
       //printf("3****************\n");
       for(int i = 0; i < n1; ++i)
       {
           T1 = SearchRoot(a1, n1);
           T2 = SearchRoot(a2, n1);
       }
//       printf("4**************%c", T1->data);
//       PreOrderTraverse(T1, Print);
//       printf("\n");
//       printf("5**************%c\n", T2->data);
//       PreOrderTraverse(T2, Print);
      if(!Compare(T1, T2))
        printf("No");
       else
        printf("Yes");
    }
}


方法二:

#include<bits/stdc++.h>
typedef struct BiTNode
{
    char data;
    int left, right;
}BiTNode;
typedef BiTNode *Node_Ptr;
typedef BiTNode *BiTree;
int root[100];
BiTree T1, T2;
int BuildTree(BiTree &T)
{
    int n;
    scanf("%d", &n);
//    getchar();
    memset(root, 0, sizeof(root));
    T = (BiTree)malloc(sizeof(BiTNode) * (n + 1));
    for(int i = 0; i < n; ++i)
    {
        getchar();
        char left, right;
        scanf("%c %c %c", &T[i].data, &left, &right);
        T[i].left = left - '0';
        T[i].right = right - '0';
        if(T[i].left < 0 || T[i].left > 9)
            T[i].left = -1;
        if(T[i].right < 0 || T[i].right > 9)
            T[i].right = -1;
        if(T[i].left != -1)
          root[T[i].left] = 1;
        if(T[i].right != -1)
          root[T[i].right] = 1;
       // printf("%c %d %d\n", T[i].data, T[i].left, T[i].right);
    }
    for(int i = 0; i < n; ++i)
        if(root[i] == 0)
          return i;
    return -1;
}
int Isostructuralism(int root1, int root2)
{
    if(root1 == root2 && root1 == -1)
        return 1;
    else
    {
        return (T1[root1].data == T2[root2].data) && (Isostructuralism(T1[root1].left, T2[root2].left) || Isostructuralism(T1[root1].left, T2[root2].right) || Isostructuralism(T1[root1].right, T2[root2].left) || Isostructuralism(T1[root1].right, T2[root2].right));
    }
    return 0;
}
int main()
{
    int n, root1, root2;
    root1 = BuildTree(T1);
    root2 = BuildTree(T2);
    int result = Isostructuralism(root1, root2);
    if(result == 1)
        printf("Yes\n");
    else
        printf("No\n");

}



举报

相关推荐

0 条评论