目录
题目描述
输入两棵二叉树A和B,判断B是不是A的子结构
测试用例
- 功能测试(树A和树B都是普通的二叉树;树B是或者不是树A的子结构)
- 特殊输入测试(两颗二叉树的一个或者两个根节点为空指针;二叉树的所有节点都没有左子树或者右子树)
题目考点
- 考察应聘者对二叉树的遍历算法的理解及递归编程能力
- 考察应聘者所写代码的鲁棒性
解题思路
代码自明(递归的方式),详细见代码注释
自己解题
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
//异常
if(root1 == null || root2 == null){
return false;
}
boolean result = false;
if(root1 != null && root2 != null){
if(Equal(root1.val, root2.val)){
result = DoesTree1HaveTree2(root1, root2);
// 实现了第一步,A中有B的根节点;
// 然后第二步,调用功能函数DoesTree1HaveTree2,判断是否含有相同子结构
}
// 上一次没有相同节点,继续遍历A的左、右子节点进行判断是否A中是否含有和B的根节点相同的节点
if(!result){
result = HasSubtree(root1.left, root2);
}
if(!result){
result = HasSubtree(root1.right, root2);
}
}
return result;
}
// ----------功能函数DoesTree1HaveTree2,判断是否含有相同结构,通过递归比较左右子节点实现--------------------
public boolean DoesTree1HaveTree2(TreeNode root1,TreeNode root2){
//异常
if(root2 == null){
return true;// 容易出错!!!
}
if(root1 == null ){
return false;
}
if(!Equal(root1.val, root2.val)){
return false;
}
return DoesTree1HaveTree2(root1.left,root2.left) && DoesTree1HaveTree2(root1.right,root2.right); // 左右子节点同时相等才为相同结构
}
//---------功能函数Equal,判断两个小数的常用方法,相差的绝对值属于一个范围----------------------
public boolean Equal(double num1, double num2){
if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001)){
return true;
}
else
return false;
}
}
参考解题
参考自己解题
补充
与二叉树相关的代码有大量的指针操作,在每次使用指针的时候,我们都要问自己这个指针有没有可能是空指针,如果是空指针则该怎么处理。
由于计算机表示小数(包括float和double型小数)都有误差,我们不能直接用等号判断两个小数是否相等。如果两个小数的差的绝对值很小,如小于0.0000001,就可以任务它们相等。
从规范性、完整性和鲁棒性3个方面提高代码质量
- 规范性:书写清晰、布局合理、命名合理
- 完整性:完成基本功能、考虑边界条件、做好错误处理
- 鲁棒性:采取防御性编程、处理无效的输入