面试题 18:树的子结构
题目:输入两颗二叉树 A 和 B,判断 B 是不是 A 的子结构。
思路
这道题不难想到用递归做会好一点,基本思路是:
①先判断两棵树的根结点值是否相同,相同则继续比较左子树,右子树的值,子树值不同返回false,子树值相同则继续向下递归比较,直到找到为止;
②如果根结点值就不相同,则对树A的左子树与树B重复上述①过程,如果找到子树返回true;
③如果②完成后没找到,则对树A的左子树与树B重复上述①过程,如果找到子树返回true,没找到则确定B不是A的子树,方法返回false。
代码
package swordOffer;
/**
* 面试题 18:树的子结构
* 题目:输入两颗二叉树 A 和 B,判断 B 是不是 A 的子结构。
*
* @author Stephen Huge
* @date 17/04/25
*/
public class Ex18JudgeSubTree {
public static void main(String[] args) {
Ex18JudgeSubTree jst = new Ex18JudgeSubTree();
BinaryNode a = new BinaryNode(2);
BinaryNode b = new BinaryNode(2);
BinaryNode c = new BinaryNode(3);
BinaryNode d = new BinaryNode(4);
BinaryNode e = new BinaryNode(5);
BinaryNode f = new BinaryNode(6);
a.lChild = b;
a.rChild = c;
b.lChild = d;
b.rChild = e;
c.lChild = f;
boolean sol = jst.judgeSubTree(a, b);
// boolean sol = jst.judgeSubTree(a, a);
// boolean sol = jst.judgeSubTree(a, jst.new BinaryNode(7));
System.out.println(sol);
}
public boolean judgeSubTree(BinaryNode biNode, BinaryNode sub) {
if(sub == null) {
return true;
}else if(biNode == null) {
return false;
}
if(biNode.data == sub.data) {
// return judgeSubTree(biNode.lChild, sub.lChild) &&
// judgeSubTree(biNode.rChild, sub.rChild);//这里要注意:如果结点值能相等,直接返回会导致判断错误
if(judgeSubTree(biNode.lChild, sub.lChild) &&
judgeSubTree(biNode.rChild, sub.rChild) == true) {
return true;
}
}
boolean result = false;
result = judgeSubTree(biNode.lChild, sub);
if(!result) {
result = judgeSubTree(biNode.rChild, sub);
}
return result;
}
// public class BinaryNode{//建议保存在新的文件中,不然在main函数新建时的方式是BinaryNode node = jsp.new BinaryNode(1);
// int data;
// BinaryNode lChild;
// BinaryNode rChild;
// public BinaryNode(int data) {
// this.data = data;
// }
// }
}
需要注意的是如果二叉树的结点值允许重复,那么根结点相同后,直接进行子树比较,找到了,直接返回true没有问题;但是如果没有找到,那么不能直接返回false,而是应该开始②,③过程,在树A的子树中继续寻找和树B根结点值相同的结点,最后得出正确结果。