题目:输入两棵二叉树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. BootStrap 智能表单系列 三 分块表单配置的介绍

    相信广大博友肯定碰到过一个编辑页面分了很多块的情况,智能表单插件已经为您支持了这种情况, 代码如下(链接地址:https://github.com/xiexingen/Bootstrap-SmartF ...

  2. sql server中关于批处理与脚本的简单介绍

    1.批处理 批处理指的是包含一条或多条T-SQL语句的语句组,这组语句从应用程序一次性地发送到SQL Server服务器执行.SQL Server服务器将批处理语句编译成一个可执行单元(即执行计划), ...

  3. iOS NSMutableURLRequest 上传图片

    - (void)postImage:(UIImage *)_image { //分界线的标识符 NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x&q ...

  4. Spring_database_Template

    配置applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans ...

  5. [NewCoder]复杂链表的复制

    看下面一个链表结点的定义: struct ComplexListNode { int val; struct ComplexListNode *next; struct ComplexListNode ...

  6. php中0,空,null和false的区别

    <? $str1 = null; $str2 = false; echo $str1==$str2 ? ‘相等’ : ‘不相等’; $str3 = ""; $str4 = 0 ...

  7. Python学习之路——初识Python

    一.第一个程序Hello World: 1.打印输出Hello World: Python2打印方法: >>> print "hello world"hello ...

  8. Ubuntu 12.04中文输入法的安装(转)

    Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等.其中Scim和Ibus是输入法框架. 在Ubuntu的中文系统中自带了中文输入法,通过Ctrl+S ...

  9. 怎么给没链接的flash加超链接

    最近开始准备设计一个广告条,本想用阿里妈妈的的banner marker来设计,却遗憾的发现,banner marker已经实行收费模式了. 我不得不启用另一款在线banner生成工具,百度旗下的&q ...

  10. C#共享内存类改进版

    原文 C#共享内存类改进版 改进说明及源码实例下载见:http://blog.csdn.net/zzh8845/archive/2008/11/22/3349963.aspx ShareMem.cs ...