题目:输入两棵二叉树A 和B。推断B 是不是A 的子结构。


二叉树结点的定义:

/**
* 二叉树的树结点
*/
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
}

解题思路:

要查找树A 中是否存在和树B 结构一样的子树。我们能够分成两步: 第一步在树A 中找到和B 的根结点的值一样的结点R。 第二步再推断树A 中以R 为根结点的子树是不是包括和树B 一样的结构。

代码实现

public class Test18 {
/**
* 二叉树的树结点
*/
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
} /**
* 输入两棵二叉树A和B,推断B是不是A的子结构。
* 该方法是在A树中找到一个与B树的根节点相等的元素的结点。
* 从这个相等的结点開始推断树B是不是树A的子结构,假设找到其的一个就返回,
* 否则直到全部的结点都找完为止。
*
* @param root1 树A的根结点
* @param root2 树B的根结点
* @return true:树B是树A的子结构,false:树B是不树A的子结构
*/
public static boolean hasSubtree(BinaryTreeNode root1, BinaryTreeNode root2) {
// 仅仅要两个对象是同一个就返回true
// 【注意此处与书本上的不同,书本上的没有这一步】
if (root1 == root2) {
return true;
} // 仅仅要树B的根结点点为空就返回true
if (root2 == null) {
return true;
} // 树B的根结点不为空。假设树A的根结点为空就返回false
if (root1 == null) {
return false;
} // 记录匹配结果
boolean result = false; // 假设结点的值相等就,调用匹配方法
if (root1.value == root2.value) {
result = match(root1, root2);
} // 假设匹配就直接返回结果
if (result) {
return true;
} // 假设不匹配就找树A的左子结点和右子结点进行推断
return hasSubtree(root1.left, root2) || hasSubtree(root1.right, root2);
} /**
* 从树A根结点root1和树B根结点root2開始。一个一个元素进行推断。推断B是不是A的子结构
*
* @param root1 树A開始匹配的根结点
* @param root2 树B開始匹配的根结点
* @return 树B是树A的子结构。false:树B是不树A的子结构
*/
public static boolean match(BinaryTreeNode root1, BinaryTreeNode root2) {
// 仅仅要两个对象是同一个就返回true
if (root1 == root2) {
return true;
} // 仅仅要树B的根结点点为空就返回true
if (root2 == null) {
return true;
}
// 树B的根结点不为空。假设树A的根结点为空就返回false
if (root1 == null) {
return false;
} // 假设两个结点的值相等,则分别推断其左子结点和右子结点
if (root1.value == root2.value) {
return match(root1.left, root2.left) && match(root1.right, root2.right);
} // 结点值不相等返回false
return false;
} public static void main(String[] args) {
BinaryTreeNode root1 = new BinaryTreeNode();
root1.value = 8;
root1.right = new BinaryTreeNode();
root1.right.value = 7;
root1.left = new BinaryTreeNode();
root1.left.value = 8;
root1.left.left = new BinaryTreeNode();
root1.left.left.value = 9;
root1.left.right = new BinaryTreeNode();
root1.left.right.value = 2;
root1.left.right.left = new BinaryTreeNode();
root1.left.right.left.left = new BinaryTreeNode();
root1.left.right.left.left.value = 4;
root1.left.right.left.right = new BinaryTreeNode();
root1.left.right.left.right.value = 7; BinaryTreeNode root2 = new BinaryTreeNode();
root2.value = 8;
root2.left = new BinaryTreeNode();
root2.left.value = 9;
root2.right = new BinaryTreeNode();
root2.right.value = 2; System.out.println(hasSubtree(root1, root2));
System.out.println(hasSubtree(root2, root1));
System.out.println(hasSubtree(root1, root1.left));
System.out.println(hasSubtree(root1, null));
System.out.println(hasSubtree(null, root2));
System.out.println(hasSubtree(null, null));
}
}

执行结果

输入的树:

输出结果:

【剑指Offer学习】【面试题18 :树的子结构】的更多相关文章

  1. 《剑指offer》面试题18 树的子结构 Java版

    (输入两棵二叉树A和B,判断B是不是A的子结构.补充下,根据书中的代码来看,子结构的定义并不包括叶子节点下的null,也就是说只要B的存在数字的结构存在于A中就行,那么如果B是null树,那么就不属于 ...

  2. 【剑指Offer】面试题26. 树的子结构

    题目 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A:      3     / \ ...

  3. 《剑指offer》面试题26. 树的子结构

    问题描述 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A:      3     / ...

  4. 剑指Offer(十七):树的子结构

    剑指Offer(十七):树的子结构 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_ ...

  5. 【剑指offer】面试题 18. 删除链表的节点

    面试题 18. 删除链表的节点

  6. 剑指Offer(书):树的子结构

    题目:输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 分析:关于二叉树大部分适应于递归结构. public boolean HasSubtree(TreeN ...

  7. (剑指Offer)面试题18:树的子结构

    题目: 输入两棵二叉树A和B,判断B是不是A的子结构. 二叉树结构定义如下: struct TreeNode{ int val; TreeNode* left; TreeNode* right; }; ...

  8. 【剑指Offer】面试题18. 删除链表的节点

    题目 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = 5 ...

  9. 《剑指offer》面试题18. 删除链表的节点

    问题描述 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = ...

  10. 【剑指Offer学习】【全部面试题汇总】

    剑指Offer学习 剑指Offer这本书已经学习完了.从中也学习到了不少的东西,如今做一个总的文件夹.供自已和大家一起參考.学如逆水行舟.不进则退.仅仅有不断地学习才干跟上时候.跟得上技术的潮流! 全 ...

随机推荐

  1. webservice主流框架Axis、Axis2、XFire、CXF的比较

    http://ws.apache.org/axis/ http://axis.apache.org/axis2/java/core/ http://xfire.codehaus.org/ http:/ ...

  2. 简单天气应用开发——API接口

    寒假回家无事,想到自学iOS开发已有一段时间,还没做过真正自己的应用,就起了做一个天气预报App的念头. 想到就做.天气预报第一步自然是找到好用的API接口来获取天气信息.在百度上搜索了一圈,找到的都 ...

  3. java和.net 处理任意格式日期字符串转日期类型,

    1.SimpleDateFormat.parse 把指定格式字符串转日期类型 public static Calendar convToCalender(String str,String templ ...

  4. (Problem 74)Digit factorial chains

    The number 145 is well known for the property that the sum of the factorial of its digits is equal t ...

  5. (IOS)悬浮按钮Demo

    思路:传入一个底层的view,将悬浮按钮(用view实现)和展开的子按钮列表add在其上,子按钮列表开始将坐标和悬浮按钮对应好后先将其隐藏,悬浮按钮识别到tap手势后触发展示子按钮列表的方法.通过在t ...

  6. 操作 IoT 设备内嵌 SQLite

    Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD   Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本 ...

  7. 2_Cat Years

    2 // // ViewController.swift // Cat Years // // Created by ZC on 16/1/6. // Copyright © 2016年 ZC. Al ...

  8. npm常用命令详解

    ~~~https://www.npmjs.org/有比较全的api文档 NPM是一个Node包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准.有了NPM,可以很快的找到特定服务要使用的 ...

  9. IC卡,ID卡,M1卡,射频卡

    一般把可读可写,频率是13.56MHz的射频卡称为IC卡,IC卡可以写入数据, 只能读,频率是125KHz的射频卡称为ID卡, M1卡是NXP公司的S50卡的一种叫法,国内的复旦F08,达华的TKS5 ...

  10. PCB的整个加工流程

    1 MI:制作生产流程卡,指导产线如何去生产出所需要的pcb.2 内层:PCB,除了最便宜的单层板,简单的双层板,有时候需要使用4层 6层 8层,以实现复杂的连 接关系和高密度,再就是减少干扰或者降低 ...