树的同构 (25分)

树的同构 (25分)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路分析:树的同构,顾名思义两个树是否有一样的结构,每一个孩子结点的孩子的数量和值都要相同,但是它所在的位置可以左右交换(不是说两个父亲结点的孩子互相交换,而是说父亲结点的下一层孩子的左右可以交换),这样就转化了越来越小的树比较是否同构,假如有两个树A,B。A树的左子树和B树的右子树同构,B树的左子树和A树的右子树同构,那么这两个树是同构的,也就是说,又回到了之前括号里面的说的,左右顺序没有关系。

我们将结点以结构体数组的方式存储,一个树就是一个结构体数组,每一个结构体数组包含的元素就是结点,每一个结点有三个信息:元素的值,左孩子的下标,右孩子的下标。我们需要直到根节点在哪里,那么从树的特征我们可以直到,根节点就是没有父亲指向它,也就是说结构体数组中的元素的左孩子下标和右孩子下标都没有指向这个结点的值。于是我们要额外创建一个数组来判断结点是否被访问比如说 int check[Maxsize]。因为题目告诉我们如果没有左右孩子,那么输入字符 ‘-’,为了能够判断输入的是数字还是字符 ‘-’,所以我们就把左孩子的下标和右孩子的下标的类型也定义为char类型,然后char类型转int类型只需要 -48 或者-'0’就可以了。

怎么判断是否同构是个难点,我们要逐一分析不同的情况:
1.当两个二叉树的根节点都为空,也就是空树,我们认为它是同构的
2.当A树有根节点,B树为空树或者当A树为空树,B树有根节点,它是不同构的
3.当A,B都有根节点,但是根节点值不相等的时候,它是不同构的
4.当A的根节点没有左孩子,B的根节点没有左孩子,这时我们要比较A的右孩子和B的右孩子是否同构
5.当A的根节点有左孩子,B的根节点也有左孩子,并且他们的值相同的时候,我们再继续比较左孩子的孩子孙子是否同构
6.当A的根节点有左孩子,但是B的根节点没有左孩子,那么我们则比较A的左孩子和B的右孩子是否同构

#define ElementType char
#define Tree int
#define Maxsize 10
#define Null -1
#include<stdio.h>
struct TreeNode
{
    Tree left,right;
    ElementType Element;
}T1[Maxsize],T2[Maxsize];

Tree BuildTree(struct TreeNode T[])
{
    int check[Maxsize];
    Tree Node,Root;
    char cl,cr;
    scanf("%d\n",&Node);
    Root = Null;
    int i =0;
    if(Node)
    {
        for(i =0; i<Node;i++) check[i] = 0;
        for(i =0; i<Node;i++)
        {
            scanf("%c %c %c\n",&T[i].Element,&cl,&cr);
            if(cl!='-')
            {
                T[i].left = cl-48;
                check[T[i].left] = 1;
            }else T[i].left = Null;
            if(cr!='-')
            {
                T[i].right = cr-48;
                check[T[i].right] = 1;
            }else T[i].right = Null;
        }
        for(i =0;i<Node;i++)
        {
            if(check[i] == 0) break;
        }
        Root = i;
    }
    return Root;
    
}

int isomorphic(Tree R1, Tree R2)
{
    if((R1==Null)&&(R2==Null)) return 1;
    if(((R1==Null)&&(R2!=Null))||((R1!=Null)&&(R2==Null))) return 0;
    if(T1[R1].Element!=T2[R2].Element) return 0;
    if((T1[R1].left == Null)&&(T2[R2].left==Null)) return isomorphic(T1[R1].right, T2[R2].right);
    if(((T1[R1].left!=Null)&&(T2[R2].left!=Null))&&((T1[T1[R1].left].Element)==(T2[T2[R2].left].Element))) return (isomorphic(T1[R1].left, T2[R2].left)&&isomorphic(T1[R1].right, T2[R2].right));
    else return(isomorphic(T1[R1].left, T2[R2].right)&&isomorphic(T1[R1].right,T2[R2].left));
}


int main()
{
    Tree R1,R2;
    int result;
    R1 = BuildTree(T1);
    R2 = BuildTree(T2);
    result = isomorphic(R1,R2);
    if(result == 0) printf("No\n");
    else printf("Yes\n");
    return 0;
}


猜你喜欢

转载自blog.csdn.net/m0_43429389/article/details/107569748