题干描述
给你两棵二叉树 root
和 subRoot
。检验 root
中是否包含和 subRoot
具有相同结构和节点值的子树。如果存在,返回 true
;否则,返回 false
。
二叉树 tree
的一棵子树包括 tree
的某个节点和这个节点的所有后代节点。tree
也可以看做它自身的一棵子树。
示例 1:
输入:root = [3,4,5,1,2], subRoot = [4,1,2] 输出:true
示例 2:
输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2] 输出:false
题干分析
根据题干要求,我们需要判断二叉树root中是否包含一棵与subRoot具有相同结构和节点值的子树。
解题思路
1.定一个节点结构:定义二叉树节点的结构以便于创建和操作树。
2.相同树判断:实现一个函数isSameTree,判断两棵树是否完全相同(包括结构和节点值)。
3.子树判断:实现一个函数isSubtree,判断subRoot是否是root的一个子树。
4.创建树节点:实现一个辅助函数newNode,用于方便地创建新的树节点。
5.测试用例:在main函数中创建测试用例,并检查程序输出是否符合预期。
代码实现
1.定义二叉树的节点结构
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
2.判断两棵树是否相同
int isSameTree(struct TreeNode* s, struct TreeNode* t) {
if (s == NULL && t == NULL) {
return 1; // 如果两棵树都为空,则相同
}
if (s == NULL || t == NULL) {
return 0; // 如果其中一棵树为空,则不相同
}
// 当前节点值相同,并递归判断左右子树
return (s->val == t->val) && isSameTree(s->left, t->left) && isSameTree(s->right, t->right);
}
3.判断subRoot是否为root的子树
int isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
if (root == NULL) {
return 0; // 如果主树为空,返回 false
}
// 检查当前树是否与子树相同,或递归检查左子树和右子树
return isSameTree(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
4.创建新节点的辅助函数
struct TreeNode* newNode(int val) {
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
node->val = val;
node->left = NULL;
node->right = NULL;
return node;
}
完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//首先先定义二叉树的节点结构
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode* right;
};
//定义一个函数用于判断两棵树是否相同
int isSameTree(struct TreeNode* s, struct TreeNode* t) {
if (s == NULL && t == NULL)
{
return 1;//两棵树均为空,则相同
}
if (s == NULL || t == NULL)
{
return 0;//其中一棵树为空,则不相同
}
// 判断当前节点的值是否相同,并递归判断左右子树
return (s->val == t->val) && isSameTree(s->left, t->left) && isSameTree(s->right, t->right);
}
//定一个函数用于判断t是否为s的子树
int isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
if (root == NULL)
{
return 0;//主树为空时,直接返回false
}
//如果当前树与目标子树相同,或者左子树或右子树与目标子树相同,则返回true
return isSameTree(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
//定义一个辅助函数用于创建新节点
struct TreeNode* newNode(int val) {
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
node->val = val;
node->left = NULL;
node->right = NULL;
return node;
}
int main() {
// 创建测试用例1
struct TreeNode* root1 = newNode(3);
root1->left = newNode(4);
root1->right = newNode(5);
root1->left->left = newNode(1);
root1->left->right = newNode(2);
struct TreeNode* subRoot1 = newNode(4);
subRoot1->left = newNode(1);
subRoot1->right = newNode(2);
printf("Test case 1: %s\n", isSubtree(root1, subRoot1) ? "true" : "false"); // 输出:true
// 创建测试用例2
struct TreeNode* root2 = newNode(3);
root2->left = newNode(4);
root2->right = newNode(5);
root2->left->left = newNode(1);
root2->left->right = newNode(2);
root2->left->right->left = newNode(0);
struct TreeNode* subRoot2 = newNode(4);
subRoot2->left = newNode(1);
subRoot2->right = newNode(2);
printf("Test case 2: %s\n", isSubtree(root2, subRoot2) ? "true" : "false"); // 输出:false
return 0;
}