题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路
- 涉及到树的问题,大多都可以用递归的方法进行解决
- 首先判断节点是否一样,如果一样,就递归判断节点的左节点和右节点;如果不一样,就转去节点的左节点和右节点递归判断
- 需要注意的问题就是递归的终止条件
- 可能root2到达空的时候,但是root1还没有为空,但是这种情况是符合树的子结构的定义的
- 当root1到达空的时候,但是root2却还没有为空,这时就不是树的子结构了=-=
AC代码
#include <iostream>
using namespace std;
typedef struct TreeNode
{
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL)
{
}
} TreeNode;
//先序创建
TreeNode *Create_tree()
{
TreeNode *T;
int val;
cin >> val;
if (val == 0) //叶子结点用0标记
return NULL;
else
{
T = new TreeNode(val);
T->left = Create_tree();
T->right = Create_tree();
}
return T;
}
//先序遍历
void pre_print(TreeNode *T)
{
if (T)
{
cout << T->val << " ";
pre_print(T->left);
pre_print(T->right);
}
}
bool is_part_of_tree(TreeNode *root1, TreeNode *root2)
{
if (root2 == NULL) //子树判断到空的位置了,可能root1数还不是为空,但是这样也是符合root2是root1的子结构的原则
return true;
if (root1 == NULL) //树为空,但是子树还没有为空,结果说明root2不是root1的子结构
return false;
if (root1->val != root2->val)
return false;
return is_part_of_tree(root1->left, root2->left) && is_part_of_tree(root1->right, root2->right);
}
//判断树的子结构
class Solution
{
public:
bool HasSubtree(TreeNode *pRoot1, TreeNode *pRoot2)
{
bool res = false;
if (pRoot1 && pRoot2)
{
if (pRoot1->val == pRoot2->val)
res = is_part_of_tree(pRoot1, pRoot2);
if (!res)
res = HasSubtree(pRoot1->left, pRoot2); //递归判断左子树
if (!res)
res = HasSubtree(pRoot1->right, pRoot2);//递归判断右子树
}
return res;
}
};
int main()
{
TreeNode *root1, *root2;
root1 = Create_tree();
cout << "第一个树的先序遍历二叉树为:";
pre_print(root1);
cout << endl;
root2 = Create_tree();
cout << "子树的先序遍历为:";
pre_print(root2);
cout << endl;
cout << "判断两个二叉树是否是嵌套关系" << endl;
Solution so;
cout << so.HasSubtree(root1, root2) << endl;
return 0;
}
/*
测试样例:
2 3 5 0 0 6 0 0 4 0 0
第一个树的先序遍历二叉树为:2 3 5 6 4
3 5 0 0 6 0 0
子树的先序遍历为:3 5 6
判断两个二叉树是否是嵌套关系
1
*/
总结
- 要注意对空指针的判断,不仅在链表中,在树形结构更要加以出现
- 对树,
用递归大法 - 要注意特殊情况的输入测试,比如空指针等等。