一棵树是否是另一棵树的子树问题

本文介绍了一种用于判断一棵二叉树是否为另一棵二叉树的子树的有效算法。首先会在主树中查找子树的根节点,若找到则进一步递归比较两树的结构是否完全相同。该算法利用了递归特性,简洁高效。

判断一个节点是否在一棵二叉树中

//判断一个节点是否在一棵二叉树中
bool IsInBinaryTreeNode(BinaryTreeNode* root, BinaryTreeNode* Node)
{
     bool res = false;
     if (root->_data == Node->_data)
          res = true;
     if (!res)//递归左子树中找
          res = IsInBinaryTreeNode(root->_left, Node);
     if (!res)//递归右子树中找
          res = IsInBinaryTreeNode(root->_right, Node);
     return res;
}

判断一颗二叉树是是否是另一颗树的子树。比如tree2是tree1的子树。

如:
这里写图片描述

判断一棵树tree2是不是另一颗树tree1的子树
第一步在tree1中找tree2的根节点,也就是2。
第一步结束后有两种情况,没找到,直接返回Tree2不是Tree1的子树;找到就进行到第二步
第二步在Tree1中2的左右节点和Tree2中2的左右节点相比较,如Tree1中根节点2的左右节点不2和7,和Tree2中的左右节点3,8不一样。
继续在Tree1中找看是否还有节点2,如果没找到,就返回不是子树。
如果找到就是图上的情况根节点的左边节点2,再和Tree2 中的左右节点进行对比,找到左右节点3,8都相同,则返回Tree2是Tree1的子树 。

//判断一颗二叉树是是否是另一颗树的子树
bool IsSubTree(BinaryTreeNode* root1, BinaryTreeNode* root2)
//判断Tree2的节点是否在Tree1中
{
     bool res = false;
     if (root1 != NULL &&  root2 != NULL)
     {
          if (root1->_data == root2->_data)//Tree2的节点在Tree1中
              res = DoesTree1HasTree2(root1,root2);
          if (!res)//递归左子树中找
              res = IsInBinaryTreeNode(root1->_left, root2);
          if (!res)//递归右子树中找
              res = IsInBinaryTreeNode(root1->_right, root2);
     }
     return res;
}
//两颗数的左右节点是否相等
bool DoesTree1HasTree2(BinaryTreeNode* root1, BinaryTreeNode* root2)
{
     if (root2 == NULL)//空树是任何树的子树
          return true;
     if (root1 == NULL)
          return false;
     if (root1->_data != root2->_data)
          return false;
     return DoesTree1HasTree2(root1->_left, root2->_left) &&
             DoesTree1HasTree2(root1->_right, root2->_right);
}
### 关于二叉是否为一棵树子树的算法实现 判断棵二叉是否是棵二叉子树个经典的递归问题。该问题的核心在于通过递归比较两棵的部分结构来验证它们的关系。 #### 方法概述 为了完成这任务,通常会设计两个辅助函数: 1. **`isSameTree`**: 用于判断两棵是否完全相同。 2. **`isSubtree`**: 用于遍历主中的每点,并将其作为潜在的根点与目标子树进行匹配。 以下是具体的实现方式: --- #### C语言实现 ```c /** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ bool isSameTree(struct TreeNode* p, struct TreeNode* q) { if (p == NULL && q == NULL) return true; // 若两者都为空,则相同 if (p == NULL || q == NULL) return false; // 若其中个为空而个不为空,则不同 if (p->val != q->val) return false; // 值不同的情况返回false return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); // 继续递归检查左右子树 } bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){ if (root == NULL) return false; // 主为空则不可能存在子树关系 if (isSameTree(root, subRoot)) return true; // 当前点满足条件时直接返回true return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot); // 向下递归寻找可能的匹配位置 } ``` 此代码实现了基本逻辑:先利用 `isSameTree` 函数逐层对比两棵的对应部分,再借助 `isSubtree` 遍历整棵以找到合适的起始点[^1]。 --- #### Java实现 ```java public class Solution { public boolean isSubtree(TreeNode s, TreeNode t) { if (s == null) return false; // 如果主已经遍历完毕仍未发现匹配项,则返回false if (isSame(s, t)) return true; // 发现有相同的子树即刻返回true return isSubtree(s.left, t) || isSubtree(s.right, t); // 对左右分支分别尝试匹配 } private boolean isSame(TreeNode s, TreeNode t) { if (s == null && t == null) return true; // 二者均无后续点视为致 if (s == null || t == null) return false; // 单侧有剩余点说明无法构成子树 if (s.val != t.val) return false; // 点值不符立即退出 return isSame(s.left, t.left) && isSame(s.right, t.right); // 进步深入检测左右孩子结点的致性 } } ``` 这段Java版本同样遵循了双层次递归的设计思路,在效率和可读性之间取得了平衡[^3]。 --- #### 时间复杂度分析 对于大小分别为 \(m\) 和 \(n\) 的两棵来说,最坏情况下需要对每对组合执行次完整的形结构比对操作,因此总体时间开销大致可以估计为 O(m \times n)[^2]。 尽管如此,实际运行过程中由于提前终止机制的存在(旦确认某处不符合即可跳过其余无关计算),平均表现往往优于理论上限。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值