一、判断两棵二叉树树是否相同
-
要求:给定两个二叉树,编写一个函数来检验它们是否相同两个
树在结构上相同,并且节点具有相同的值,则认为它们是相同的 -
分析:有序树结构相同值域相同
-
思路:
1、题中未说明二叉树是否未空树,需要考虑极端情况
if(p == null && q == null) //约定两棵空树相同 return true
if(p == null || q == null) //在上一个条件不成立满足其中一个为空 return false
2、两棵不为空的二叉树,首先判断值域是否相同
if (p.val != q.val) //值域不相同 return false
3、若当前结点值域相同则要不断判断左右子树是否相同,这里要用递归的思想
有相同子问题:不断比较当前结点的左右子树的子树(...)直至整棵树的最后一个叶结点
每个子问题终止条件:当前叶节点的左右子树均为空
注意这里递归的出口条件和极端情况并不矛盾,如果出现矛盾需要考虑别的情况
public boolean isSameTree(TreeNode p, TreeNode q) {
//如果是两棵空树
if(p == null && q == null) {
return true;
}
//如果两棵树中至少由一棵树是空树
if(p == null || q == null) {
return false;
}
//如果两颗树的值域不相同
if(p.val != q.val) {
return false;
}
//通过判断左右子树来判别是否相同
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
二、另一棵树的子树
- 要求:
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的
一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。 - 分析:两棵非空二叉树、s 中是否有 t 的子树、两棵相同的树也是子树情况
- 思路:
1、题目中表明了非空二叉树 s、t,没有极端情况
2、 两棵二叉树不相同的情况,不断判断 s 中左右子树是否有和 t 相同的部分,同样是一个递归问题
相同子问题:不断遍历 s 当前结点的子树的子树(...)与 t 比较是否相同,给出返回值
终止条件:
if(s == null) // s遍历完之前都没有返回说明没有相同子树 return false
if(t == null) // t 遍历完之前都没有返回说明找到了相同子树 return true
3、两棵二叉树相同,判断方法借助上述一
public boolean isSubtree(TreeNode s, TreeNode t) {
//始终不要忘了递归的出口,不能忽略了子树的情况
if(t == null ){
return true;
}
if(s == null) {
return false;
}
//两棵二叉树相同的情况不考虑
if((s.val == t.val) && isSameTree(s,t)) {
return true;
}
//t 是 s 的子树
//上面已经提高效率,在判断子树相同的时候就可以避免根节点相同的情况了
return isSubtree(s.left,t) || isSubtree(s.right,t);
}
private boolean isSameTree(TreeNode s,TreeNode t) {
if(s== null && t == null){
return true;
}
if(s == null || t == null) {
return false;
}
if (s.val != t.val) {
return false;
}
return isSameTree(s.left,t.left) && isSameTree(s.right,t.right);
}