You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断给定的多叉树是否为另一棵多叉树的子结构

判断多叉树B是否为多叉树A的子结构

核心定义

首先明确子结构的含义:存在A中的某个节点,从该节点出发,其节点值、层级结构与B完全一致——B的每个节点都能在A的对应位置找到匹配的节点(值相等),且B的所有子节点都能对应A中该节点的子节点部分(注意:子结构≠子树,子树要求包含节点的所有后代,而子结构只要求匹配B的完整结构)。

解决思路

分两步处理:

  1. 匹配检查:写一个递归函数,判断以A中某个节点为根的子树是否和B完全匹配。
  2. 遍历搜索:遍历A的所有节点,对每个节点调用匹配检查函数,只要有一个节点匹配成功,就说明B是A的子结构。

代码实现(有序多叉树)

假设多叉树节点结构如下:

class TreeNode:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children if children is not None else []

1. 匹配检查函数

判断两个节点为根的树是否结构和值完全匹配(子节点顺序一致):

def is_match(node_a, node_b):
    # B的当前节点为空,说明这部分匹配完成
    if not node_b:
        return True
    # A的当前节点为空但B不为空,匹配失败
    if not node_a:
        return False
    # 节点值不相等,直接失败
    if node_a.val != node_b.val:
        return False
    # 子节点数量不一致,结构不匹配
    if len(node_a.children) != len(node_b.children):
        return False
    # 逐个递归匹配子节点
    for child_a, child_b in zip(node_a.children, node_b.children):
        if not is_match(child_a, child_b):
            return False
    return True

2. 主搜索函数

遍历A的所有节点,寻找是否存在匹配的子结构:

def has_substructure(root_a, root_b):
    # 边界情况:空树是任何树的子结构
    if not root_b:
        return True
    # A为空但B不为空,不可能匹配
    if not root_a:
        return False
    # 先检查当前节点是否匹配
    if is_match(root_a, root_b):
        return True
    # 递归检查A的所有子节点
    for child in root_a.children:
        if has_substructure(child, root_b):
            return True
    # 所有节点都不匹配
    return False

无序多叉树的适配

如果多叉树的子节点顺序不影响匹配(即子节点的排列顺序无关),需要修改匹配函数,确保B的每个子节点都能在A的子节点中找到唯一匹配:

def is_match_unordered(node_a, node_b):
    if not node_b:
        return True
    if not node_a or node_a.val != node_b.val:
        return False
    # 复制A的子节点列表,避免修改原数据
    available_children = node_a.children.copy()
    for child_b in node_b.children:
        matched = False
        for idx, child_a in enumerate(available_children):
            if is_match_unordered(child_a, child_b):
                # 匹配成功后移除该子节点,防止重复匹配
                available_children.pop(idx)
                matched = True
                break
        if not matched:
            return False
    return True

此时主搜索函数只需将is_match替换为is_match_unordered即可。

注意事项

  • 节点值比较:如果节点值是复杂对象,需要自定义相等判断逻辑,不能直接用!=。
  • 空树规则:若业务中不认为空树是子结构,可修改边界条件,将if not root_b: return True改为if not root_b: return False。
  • 性能优化:对于大型树,可提前剪枝(比如节点值不匹配时直接跳过该节点的子树遍历)。

内容的提问来源于stack exchange,提问作者irasin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:20:38