C++判断两个二叉树是否同构

本文是依据陈越、何钦铭在中国大学MOOC网上第三讲《树》中的小白专场《如何判别两二叉树同构》而撰成。
https://www.icourse163.org/learn/ZJU-93001?tid=1207006212#/learn/content?type=detail&id=1212031634&cid=1215166211
题目描述:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
课程中采用结构数组构成的静态链表来实现这道题,A、B、C等这些结点在数组中的存储形式如下:
在这里插入图片描述
其中Left,Right表示其对应结点的左儿子、右儿子在数组中的下标,若Left或Right的值为-1,则表示该结点没有左儿子或右儿子,若Left值为2,则表示该结点的左儿子存在结构数组中下标为2的空间中。

程序的实现主要依据两个函数,一是BuilTree(),其作用是根据输入的值构建一棵二叉树,并返回二叉树的根结点在结构数组中的下标值;一是Isomorphic(),其作用是根据BuilTree返回的两棵二叉树根节点的值,比较两棵二叉树是否同构。
完整程序如下:

#include <iostream>
#define MaxTree 10
#define Null -1
using namespace std;
typedef char ElementType;
struct TreeNode
{
    ElementType Element;
    int Left;
    int Right;
}T1[MaxTree],T2[MaxTree];

int main()
{
    int BuildTree(TreeNode T[]);
    int Isomorphic(int R1,int R2);
    int R1,R2;
    R1=BuildTree(T1);
    R2=BuildTree(T2);
    if(Isomorphic(R1,R2))
        cout<<"Yes"<<endl;
    else
        cout<<"No"<<endl;
    return 0;
}

int BuildTree(TreeNode T[])
{
    int N,i,Root;
    cout<<"N=";
    cin>>N;
    int check[N];
    ElementType cl,cr;
    if(N){
        for(i=0;i<N;i++) check[i]=0;
        for(i=0;i<N;i++){
            cin>>T[i].Element>>cl>>cr;
            if(cl!='-'){
                T[i].Left=cl-'0';
                check[T[i].Left]=1;
            }
            else
                T[i].Left=Null;
            if(cr!='-'){
                T[i].Right=cr-'0';
                check[T[i].Right]=1;
            }
            else
                T[i].Right=Null;
        }
        for(i=0;i<N;i++)
            if(!check[i]) break;
        Root=i;  //记Root为根节点在数组中的下标
    }
    return(Root);
}

int Isomorphic(int R1,int 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));
}
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
判断两个二叉树是否同构可以使用递归和分治法思想,下面是两种实现方式: 1. 递归实现 递归实现的思路是分别判断两个二叉树的左子树和右子树是否同构,如果左右子树都同构,则判断两个二叉树的根节点是否相同。代码如下: ```python def is_isomorphic(root1, root2): if not root1 and not root2: return True if not root1 or not root2: return False if root1.val != root2.val: return False return (is_isomorphic(root1.left, root2.left) and is_isomorphic(root1.right, root2.right)) or \ (is_isomorphic(root1.left, root2.right) and is_isomorphic(root1.right, root2.left)) ``` 2. 分治实现 分治实现的思路是将两个二叉树分别划分成左子树和右子树,然后递归判断左子树和右子树是否同构,最后判断两个二叉树的根节点是否相同。代码如下: ```python def is_isomorphic(root1, root2): if not root1 and not root2: return True if not root1 or not root2: return False if root1.val != root2.val: return False return (is_isomorphic(root1.left, root2.left) and is_isomorphic(root1.right, root2.right)) or \ (is_isomorphic(root1.left, root2.right) and is_isomorphic(root1.right, root2.left)) def is_isomorphic_dc(root1, root2): if not root1 and not root2: return True if not root1 or not root2: return False if root1.val != root2.val: return False return is_isomorphic_dc(root1.left, root2.left) and \ is_isomorphic_dc(root1.right, root2.right) and \ is_isomorphic_dc(root1.left, root2.right) and \ is_isomorphic_dc(root1.right, root2.left) ``` 以上两种方法都可以判断两个二叉树是否同构,其中递归实现的代码比较简洁,分治实现的代码稍微复杂一些,但是思路清晰。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值