树的同构问题--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),用于存储树的结构和递归调用栈

四、个人总结

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

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

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

相关推荐
CHNMSCS19 分钟前
PyTorch_指定运算设备 (包含安装 GPU 的 PyTorch)
人工智能·pytorch·python
EanoJiang22 分钟前
查找
算法
Stay Passion1 小时前
Java 实用工具类:Apache Commons IO 的 IOUtils
java·开发语言·apache
海码0072 小时前
【Hot 100】 146. LRU 缓存
数据结构·c++·算法·链表·缓存·hot100
买了一束花3 小时前
二、机器学习中Python变量基础
开发语言·python·机器学习·conda
钢铁男儿3 小时前
C# 方法(控制流和方法调用)
算法
heyCHEEMS3 小时前
最大子段和 Java
java·开发语言·算法
Gui林3 小时前
ros2 humble 控制真实机械臂(以lerobot为例)
linux·python
我是一只鱼02233 小时前
LeetCode算法题 (设计链表)Day16!!!C/C++
数据结构·c++·算法·leetcode·链表
钢铁男儿4 小时前
Python基本语法(函数partial)
前端·javascript·python