二叉树面试题之判断一棵树是否为另一棵树的子树

判断一棵树是否为另一棵树的子树
题目:二叉树的结点定义如下:

struct TreeNode
{
        int m_nValue;
        TreeNode* m_pLeft;
        TreeNode* m_pRight;
};

输入两棵二叉树A和B,判断树B是不是A的子结构。
例如,下图中的两棵树A和B,由于A中有一部分子树的结构和B是一样的,因此B就是A的子结构。

   A树              1                                               B树                8
                     /   \                                                                  /   \
                   8    7                                                               9     2
                 /   \
               9     2
              /  \
            4    7
分析:这是一道二叉树很经典的题目。二叉树一直是面试题中经常出现的数据结构。对数据结构有兴趣的一定要重点关注二叉树。
回到这个题目的本身。要查找树A中是否存在和树B结构一样的子树,我们可以分为两步:

       第一步在树A中找到和B的根结点的值一样的结点N,

       第二步再判断树A中以N为根结点的子树是不是包括和树B一样的结构。
第一步在树A中查找与根结点的值一样的结点。这实际上就是树的遍历。对二叉树这种数据结构熟悉的读者自然知道我们可以用递归的方法去遍历,也可以用循环的方法去遍历。由于递归的代码实现比较简洁,面试时如果没有特别要求,我们通常都会采用递归的方式。下面是参考代码:

首先要注意查边界条件:

bool HasSubtree(TreeNode*TreeHead1, TreeNode*TreeHead2)
{
	if ((TreeHead1 == NULL&&TreeHead2 != NULL) || (TreeHead1 1 = NULL&&TreeHead2 == NULL))
		return false;
	if (TreeHead1 == NULL&&TreeHead2 == NULL)
		return true;
	return HasSubtreeCore(TreeHead1, TreeHead2);
}
bool HasSubtreeCore(TreeNode*TreeHead1, TreeNode*TreeHead2)
{
	bool result = false;
	if (TreeHead1->_value == TreeHead2->_value)
		result = AllTree2(TreeHead1, TreeHead2);
	if (!result&& TreeHead1->_left != NULL)
		result = AllTree2(TreeHead1->_left, TreeHead2);
	if (!result&& TreeHead1->_right != NULL)
		result = AllTree2(TreeHead1->_right, TreeHead2);
	return result;
}
在上述代码中,我们递归调用hasSubtreeCore()函数遍历二叉树A。如果发现某一结点的值和树B的头结点的值相同,则调用AllTree2(),做第二步判断。
  一定要注意边界条件的检查,即检查空指针。当树A或树B为空的时候,定义相应的输出。如果没有检查并做相应的处理,程序非常容易崩溃,由于没有必要在每一次递归中做边界检查(每一次递归都做检查,增加了不必要的时间开销),上述代码只在HasSubtree()中作了边界检查后,在HasSubtreeCore()中作递归遍历。
接下来考虑第二步,判断以树A中以N为根结点的子树是不是和树B具有相同的结构。同样,我们也可以用递归的思路来考虑:如果结点N的值和树B的根结点不相同,则以N为根结点的子树和树B肯定不具有相同的结点;如果他们的值相同,则递归地判断他们的各自的左右结点的值是不是相同。递归的终止条件是我们到达了树A或者树B的叶结点。参考代码如下:

bool AllTree2(TreeNode*TreeHead1, TreeNode*TreeHead2)
{
	if (TreeHead2 == NULL)
		return true;
	if (TreeHead1 == NULL)
		return false;
	if (TreeHead1->_value != TreeHead2->_value)
		return false;
	return AllTree2(TreeHead1->_left, TreeHead2) && AllTree2(TreeHead1->_right, TreeHead2);
}


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
判断一个二叉树是否为另一棵树子树,可以采用递归的方法,先判断当前根节点是否相同,若相同则递归判断左右子树是否相同,若不同则递归判断二叉树的左右子树是否为目标树的子树。 具体实现步骤如下: 1. 判断当前节点是否为空,若为空则返回 false。 2. 判断当前节点是否与目标树的根节点相同,若相同则递归判断左右子树是否相同。 3. 若当前节点与目标树的根节点不同,则递归判断二叉树的左右子树是否为目标树的子树。 具体实现代码如下(假设 TreeNode 为二叉树节点的数据结构): ``` bool isSubtree(TreeNode* s, TreeNode* t) { if (!s) return false; // 若当前节点为空,返回 false if (isSameTree(s, t)) return true; // 若当前节点与目标树根节点相同,递归判断左右子树是否相同 return isSubtree(s->left, t) || isSubtree(s->right, t); // 若不同,则递归判断二叉树的左右子树是否为目标树的子树 } bool isSameTree(TreeNode* p, TreeNode* q) { if (!p && !q) return true; // 若两个节点均为空,返回 true if (!p || !q) return false; // 若其中一个节点为空,返回 false if (p->val != q->val) return false; // 若两个节点的值不同,返回 false return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); // 递归判断左右子树是否相同 } ``` 其中 isSameTree 函数用于判断两个节点以及它们的子树是否相同。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值