树的同构的个人理解

题目就不打了,附上PTA原文链接就算了
直接上代码

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

#define MaxTree 10
#define ElementType char
#define Tree int
#define Null -1

struct TreeNode
{
    ElementType e;
    Tree left;
    Tree right;
}T1[MaxTree],T2[MaxTree];

Tree BuildTree ( struct TreeNode T[]);
int Isomorphic(Tree R1,Tree R2);

int main()
{
    Tree R1,R2;

    R1 = BuildTree(T1);
    R2 = BuildTree(T2);
    if( Isomorphic(R1,R2)){
        printf("Yes\n");
    }
    else{
        printf("No\n");
    }
    return 0;

}

Tree BuildTree ( struct TreeNode T[])
{

    int i;
    int n;
    int check[MaxTree];
    char cl,cr;
    Tree root =Null;   //若n为0,返回Null

    scanf("%d",&n);
    if( n ){
        for( i=0; i<n; i++){
            check[i] = 0;
        }
        for( i=0; i<n; i++){
            scanf("\n%c %c %c",&T[i].e,&cl,&cr);
            if( cl!='-' ){
                T[i].left = cl-'0';   //若输入不为'-',那字符减去字符0转换为整型数值
                check[T[i].left] = 1; //把在静态链表中出现过的数值标记为1
            }
            else if( cl=='-' ){
                T[i].left = Null;
            }
            if( cr!='-' ){
                T[i].right = cr-'0';
                check[T[i].right] = 1;
            }
            else if( cr=='-' ){
                T[i].right = Null;
            }
        }

        for( i=0; i<n; i++){
            if( !check[i]){
                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].e)!=(T2[R2].e))//如果数据不同则不是同构的
        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].e)==(T2[T2[R2].left].e)) )
        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 ) );

}

主要流程不谈,具体可看MOOC小白专场

看到判断是否同构的函数,都开始有点怀疑自己学的C语言,
然后又去找了找判断二叉树是否相同的函数,代码如下

//二叉树节点结构体
struct BinaryNode
{
    int data;
    BinaryNode * lc;
    BinaryNode * rc;
}*BTree;

//判断二叉树是否相等的函数

bool isEqual(BTree T1,BTree T2)
{
    if(T1 == NULL && T2 == NULL)
        return true;//都为空,相等。
    if(!T1||!T2)    //由于上面的判断不成立,则T1,T2至少有一个不为空
        return false;//一个空,一个不空,不相等
    if(T1->data == T2->data) //如果根节点相等
        return isEqual(T1->lc,T2->lc) && isEqual(T1->rc,T2->rc);//判断左右子树是否都相等
    else 
        return false;
}

算法思想:先序遍历,递归实现。先判断根节点是否相等,然后在判断左右子树是否相等。

两者的区别在于
前者是同构,有交换左右子树也判断正确的情况,导致多了最后三个的分类讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值