剑指offer之面试题26:树的子结构

树的子结构

1、题目

输入两颗二叉树A和B,判断B是不是A的子结构。二叉树节点的定义如下:

struct BinaryTreeNode
{
	double m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

输入参数:二叉树根节点1,二叉树根节点2

输出结果:true 或 false

2、解题

此题的关键主要在于两个递归

  • 第一个递归是找到树A第一个和树B的根节点值一样的节点R
  • 第二个递归是找到节点R后与树B剩余节点的比较

此题可分为两个步骤

  • 在树A中查找与根节点值一样的节点R,即树的遍历,用递归实现即可
  • 判断树A中以R为根节点的子树和树B是否有相同结构,同样可以用递归实现
3、完整代码
bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) {
	bool result = false;
	//必要的鲁棒性检查
	if(pRoot1 != nullptr && pRoot2 != nullptr){
		if (Equal(pRoot1->m_nValue, pRoot2->m_nValue))
			result = DoesTree1HasTree2(pRoot1, pRoot2);
		if (!result) {
			result = HasSubtree(pRoot1->m_pLeft, pRoot2);
		}
		if (!result) {
			result = HasSubtree(pRoot1->m_pRight, pRoot2);
		}
	}
	//返回结果
	return result;
}

bool DoesTree1HasTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) {
	//首先对结束条件做判断
	if (pRoot2 == nullptr)
		return true;
	if (pRoot1 == nullptr)
		return false;
	//对根节点的值进行比较,若不相等,直接返回false
	if (!Equal(pRoot1->m_nValue, pRoot2->m_nValue))
		return false;
	//否则继续对左右子树进行比较
	return DoesTree1HasTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) && DoesTree1HasTree2(pRoot1->m_pRight, pRoot2->m_pRight);
}

bool Equal(double num1, double num2) {
	if ((num1 - num2 > -0.0000001) && (num1 - num2) < 0.0000001)
		return true;
	else
		return false;
}
4、注意点
  • 代码的鲁棒性,有多处地方需要对参数是否为空指针进行处理
  • 找到根节点时,遍历的结束条件是是否到达树B的叶节点,即所有节点对比结束
  • 递归的逻辑,先对根节点的值进行对比,再递归其子树,需要理清其中的逻辑
  • 尽管在首次进入DoesTree1HasTree2()函数之前需要将已经比较的根节点的值再比较一遍,但这是必要的,否则后面的递归调用就无法比较了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值