1、题目:输入两棵二叉树A和B,判断B是不是A的子结构。
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
解法:
分成两步:一在树A中找到和B的跟结点的值一样的结点R,二判断树A中以R为根结点的子树是不是包含和树B一样的结构。第一步中实际就是树的遍历,可以用递归或循环实现。
bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
bool result = false;
if(pRoot1 != NULL && pRoot2 != NULL)
{
if(pRoot1->m_nValue == pRoot2->m_nValue)
result = DoseTree1HaveTree2(pRoot1, pRoot2);
if(! result)
result = HasSubtree(pRoot1->m_pLeft, pRoot2);
if(! result)
result = HasSubtree(pRoot1->m_pRight, pRoot2);
}
return result;
}
上述代码中,递归调用HasSubtree遍历二叉树A。如果发现某一结点的值和树B的头结点的值相同,则调用DoesTreeHaveTree2,做第二步判断。
2、第二步判断中,同样以递归实现,如果结点R的值和树B的根结点不相同,则以R为根结点的子树和树B肯定不具有相同的结点;如果他们的值相同,则递归地判断他们各自的左右结点的值是不是相同。递归的终止条件是到达了树A或树B的叶结点。
bool DoseTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
if(pRoot2 == NULL)
return true;
if(pRoot1 == NULL)
return false;
if(pRoot1->m_nValue != pRoot2->m_nValue)
return false;
return DoseTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
DoseTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
}
3、注意:一定要注意边界条件的检查,即检查空指针。要养成一种习惯,在每一处需要访问地址的时候都要问自己这个地址有没有可能是NULL,如果是NULL该怎么处理。