剑指offer解题报告(Java版)——树的子结构 18

   

引言

   

继续二叉树的狂轰乱炸,这道题很简单,就是一个二叉树的递归问题

   

分析问题

   

要判断树B是否为树A的子结构,可以分为两步,第一步找到两棵树中节点相同的根节点R

   

然后判断A中以R为根节点的子树是否包含树B,比如以下两棵树,我们知道子树B的根节点是8,所以我们在A中从根节点开始找,找8,发现根节点就是8,于是我们分别去看8的左孩子,发现A中8的左孩子是8,而B中8的左孩子是9,对不上号

   

于是抛弃这个8,在在左子树中寻找8,发现左孩子为8,然后也去看8的左右孩子是否能对上号,发现可以,于是返回true,如果对不上,那么遍历左右子树,寻找到8,然后匹配

   

   

   

   

解决问题

   

首先我们需要有一个函数去找A中的8

   

寻找函数

   

public boolean hasSubTree(BinaryTreeNode root1,BinaryTreeNode root2)

{

if(root2==null)

return true;

else

if(root1==null)

return false;

boolean result=false;

if(root1!=null && root2!=null)

{

if(root1.data==root2.data)

result=doesTree1HaveTree2(root1, root2);

if(!result)

return hasSubTree(root1.leftNode, root2) || hasSubTree(root1.rightNode, root2);

}

return result;

}

   

传入的参数有两个,也就是两个树的根节点,如果root2为空,那么root1肯定包含root2,返回true,如果root1为空,那么必定为false,这是Corner case,要注意检验

   

然后就是看root1和root2是否相等,如果相等,就去逐个比较左右孩子,这个我们另外写一个函数实现,函数返回是个布尔值,表示是否匹配成功

   

如果不等,我们就需要递归到左子树和右子树中去寻找了,因为每个寻找函数hasSubTree中都包含了子树匹配的函数doesTree1HaveTree2,所以我们只需要调用寻找函数就行了

   

接下来我们看如何逐个匹配

   

子树匹配

   

public boolean doesTree1HaveTree2(BinaryTreeNode root1,BinaryTreeNode root2)

{

if(root2==null)

return true;

else

if(root1==null)

return false;

if(root1.data!=root2.data)

return false;

else {

return doesTree1HaveTree2(root1.leftNode, root2.leftNode) && doesTree1HaveTree2(root1.rightNode, root2.rightNode);

}

}

   

子树匹配也是传入两个根节点,如果root2为空,说明肯定匹配上了,如果root1为空,那么说明肯定匹配不上了,这个跟刚才的一样

   

然后如果都不为空,就需要比较这两个根节点的值是否相等,如果不相等,那好,不用比了,肯定匹配不上,如果相等,那么需要递归到左右子树去比较了,而且必须要左右子树都能匹配上才行

   

测试代码

   

public static void main(String args[])

{

BinaryTreeNode root1=new BinaryTreeNode();

BinaryTreeNode node1=new BinaryTreeNode();

BinaryTreeNode node2=new BinaryTreeNode();

BinaryTreeNode node3=new BinaryTreeNode();

BinaryTreeNode node4=new BinaryTreeNode();

BinaryTreeNode node5=new BinaryTreeNode();

BinaryTreeNode node6=new BinaryTreeNode();

root1.leftNode=node1;

root1.rightNode=node2;

node1.leftNode=node3;

node1.rightNode=node4;

node4.leftNode=node5;

node4.rightNode=node6;

root1.data=8;

node1.data=8;

node2.data=7;

node3.data=9;

node4.data=2;

node5.data=4;

node6.data=7;

BinaryTreeNode root2=new BinaryTreeNode();

BinaryTreeNode a=new BinaryTreeNode();

BinaryTreeNode b=new BinaryTreeNode();

root2.leftNode=a;

root2.rightNode=b;

root2.data=8;

a.data=9;

b.data=2;

DoesTree1HaveTree2 test=new DoesTree1HaveTree2();

System.out.println(test.hasSubTree(root1, root2));

   

}

   

posted @ 2015-04-29 21:15  keedor  阅读(265)  评论(0编辑  收藏  举报