树的同构问题--Python

树的同构问题

一、问题引入

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

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

输入格式:

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

输出格式:

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

输入样例:

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 -

输出样例:

Yes

二、问题分析

1.思维导图

2.解决步骤

  1. 输入处理
    • 读取每棵树的节点数
    • 为每棵树构建节点信息和子节点关系
    • 确定每棵树的根节点(没有父节点的节点)
  2. 同构判断
    • 基本情况处理:
    ◦ 如果两个根节点都为空,返回True
    ◦ 如果一个为空另一个不为空,返回False
    ◦ 如果根节点存储的值不同,返回False
    • 递归比较:
    ◦ 情况1:不交换左右子树进行比较
    ◦ 情况2:交换左右子树进行比较
    ◦ 只要有一种情况匹配就返回True
  3. 结果输出
    • 根据递归比较结果输出"Yes"或"No"

三、代码实现

代码

python 复制代码
def read_tree(n):
    nodes = {}
    children = {}
    has_parent = [False] * n
    for i in range(n):
        data, left, right = input().split()
        nodes[i] = data
        left = int(left) if left != '-' else None
        right = int(right) if right != '-' else None
        children[i] = (left, right)
        if left is not None:
            has_parent[left] = True
        if right is not None:
            has_parent[right] = True
    root = None
    for i in range(n):
        if not has_parent[i]:
            root = i
            break
    return nodes, children, root

def is_isomorphic(root1, root2, nodes1, nodes2, children1, children2):
    if root1 is None and root2 is None:
        return True
    if root1 is None or root2 is None:
        return False
    if nodes1[root1] != nodes2[root2]:
        return False
    # Compare without swapping
    left1, right1 = children1[root1]
    left2, right2 = children2[root2]
    case1 = is_isomorphic(left1, left2, nodes1, nodes2, children1, children2) and \
            is_isomorphic(right1, right2, nodes1, nodes2, children1, children2)
    # Compare with swapping
    case2 = is_isomorphic(left1, right2, nodes1, nodes2, children1, children2) and \
            is_isomorphic(right1, left2, nodes1, nodes2, children1, children2)
    return case1 or case2

n1 = int(input())
nodes1, children1, root1 = read_tree(n1)
n2 = int(input())
nodes2, children2, root2 = read_tree(n2)

if is_isomorphic(root1, root2, nodes1, nodes2, children1, children2):
    print("Yes")
else:
    print("No")

算法分析

  1. 时间复杂度:O(n²),在最坏情况下需要比较所有节点的组合
  2. 空间复杂度:O(n),用于存储树的结构和递归调用栈

四、个人总结

通过本次实验,我对树的同构问题有了更深入的理解。在解决问题的过程中,我学会了如何从实际问题出发,将抽象的树结构转化为具体的代码实现。实验初期,我一度困惑于如何判断两棵树是否同构,但通过仔细分析题目示例,我逐渐认识到关键在于递归地比较节点的值及其子树结构。

在实现过程中,我掌握了处理树形结构输入的有效方法,特别是如何通过标记父节点来准确找到树的根节点。这次实验让我深刻体会到递归思想在解决树结构问题中的强大作用,通过将大问题分解为相同性质的子问题,可以优雅地解决看似复杂的结构匹配问题。同时,我也认识到边界条件处理的重要性,比如空树情况的处理、单节点树的比较等细节都会直接影响程序的正确性。

在调试过程中,我通过打印中间结果验证了递归调用的正确性,这让我对递归的执行过程有了更直观的认识。此外,本次实验还让我意识到算法效率的重要性,虽然递归解法简洁易懂,但在处理大规模数据时可能面临性能问题。总的来说,这次实验不仅让我掌握了树同构问题的解决方法,更重要的是培养了我分析问题、设计算法的能力,这对今后学习更复杂的数据结构和算法打下了坚实基础。

相关推荐
万粉变现经纪人15 分钟前
如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘tokenizers’ 问题
python·selenium·测试工具·scrapy·beautifulsoup·fastapi·pip
机器学习之心1 小时前
多目标鲸鱼优化算法(NSWOA),含46种测试函数和9个评价指标,MATLAB实现
算法·matlab·多目标鲸鱼优化算法·46种测试函数·9个评价指标
西阳未落2 小时前
C++基础(21)——内存管理
开发语言·c++·面试
编程武士2 小时前
从50ms到30ms:YOLOv10部署中图像预处理的性能优化实践
人工智能·python·yolo·性能优化
我的xiaodoujiao2 小时前
Windows系统Web UI自动化测试学习系列2--环境搭建--Python-PyCharm-Selenium
开发语言·python·测试工具
max5006002 小时前
基于Meta Llama的二语习得学习者行为预测计算模型
人工智能·算法·机器学习·分类·数据挖掘·llama
callJJ2 小时前
从 0 开始理解 Spring 的核心思想 —— IoC 和 DI(2)
java·开发语言·后端·spring·ioc·di
王哥儿聊AI3 小时前
Lynx:新一代个性化视频生成模型,单图即可生成视频,重新定义身份一致性与视觉质量
人工智能·算法·安全·机器学习·音视频·软件工程
hsjkdhs4 小时前
万字详解C++之构造函数析构函数
开发语言·c++
Lin_Aries_04215 小时前
容器化简单的 Java 应用程序
java·linux·运维·开发语言·docker·容器·rpc