面试题18:树的子结构
题目:输入两棵二叉树A和B,判断B是不是A的子结构。二叉树结点的定义如下:
struct BinaryTreeNode
{int value;BinaryTreeNode *lchild;BinaryTreeNode *rchild;
};
代码如下:
bool HasSubtree(BinaryTreeNode *pRoot1, BinaryTreeNode *pRoot2)
{bool res = false;if (pRoot1 != nullptr && pRoot2 != nullptr){if (pRoot1->value == pRoot2->value) res = DoesTree1HaveTree2(pRoot1, pRoot2);if (!res) res = HasSubtree(pRoot1->lchild, pRoot2);if (!res) res = HasSubtree(pRoot1->rchild, pRoot2);}return res;
}bool DoesTree1HaveTree2(BinaryTreeNode *pRoot1, BinaryTreeNode *pRoot2)
{if (pRoot2 == nullptr) return true;if (pRoot1 == nullptr) return true;if (pRoot1->value != pRoot2->value) return false;return DoesTree1HaveTree2(pRoot1->lchild, pRoot2->lchild) && DoesTree1HaveTree2(pRoot1->rchild, pRoot2->rchild);
}
面试小提示:
二叉树相关的代码有大量的指针操作,每一次使用指针的时候,我们都要问自己这个指针有没有可能是NULL,如果是NULL该怎么处理。
为了确保自己的代码完整正确,在写出代码之后应聘者至少要用几个测试用例来检验自己的程序:
- 树A和树B的头结点有一个或者两个都是空指针
- 在树A和树B中所有结点都只有左子结点或者右子结点
- 树A和树B的结点中含有分叉
只有这样才能写出让面试官满意的鲁棒代码。
● 功能测试(树A和树B都是普通的二叉树,树B是或者不是树A的子结构)。
● 特殊输入测试(两棵二叉树的一个或者两个根结点为NULL指针、二叉树的所有结点都没有左子树或者右子树)。
本题考点:
● 考查对二叉树遍历算法的理解及递归编程能力。
● 考查代码的鲁棒性。本题的代码中含有大量的指针操作,稍有不慎程序就会崩溃。应聘者需要采用防御性编程的方式,每次访问指针地址之前都要考虑这个指针有没有可能是NULL。