• 剑指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));

       

    }

       

  • 相关阅读:
    Linux 基础命令3 shell
    Django 的学习(2) 从adminuser到配置
    Linux巨好用的
    常见任务&基本工具 1 软件包管理
    java学习补全 1
    基础命令1
    java 5 绘图GUI
    Open GL与OpenGLES
    NDK 安装步骤
    转:为什么要有handler机制?
  • 原文地址:https://www.cnblogs.com/keedor/p/4467079.html
Copyright © 2020-2023  润新知