题目:输入两棵二叉树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. $timeout, $interval

    $timeout, $interval   layout: posttitle: Angular@1.4.3 中文 API 服务篇 $timeout & $intervaldesc: '$ti ...

  2. ViewState是什么

    在做ASP.NET的时候遇到ViewState,当时不知道他是什么意思. 就在当前页面中保存数据的. 像session.是会话级别的.只要会话没有过期.session中存的数据就在. viewstat ...

  3. poj2032Square Carpets(IDA* + dancing links)

    题目请戳这里 题目大意:给一个H行W列的01矩阵,求最少用多少个正方形框住所有的1. 题目分析:又是一个红果果的重复覆盖模型.DLX搞之! 枚举矩阵所有的子正方形,全1的话建图.判断全1的时候,用了一 ...

  4. UVA 10798 - Be wary of Roses (bfs+hash)

    10798 - Be wary of Roses You've always been proud of your prize rose garden. However, some jealous f ...

  5. 解决python2.7.9以下版本requests访问https的问题

    在python2.7.9以下版本requests访问https连接后,总会报一些关于SSL warning. 解决法子可以参考:https://urllib3.readthedocs.io/en/la ...

  6. OutputDebugString 输出信息到调试器

    #include <Windows.h>#include <stdio.h>#include <stdarg.h> void __cdecl odprintf(co ...

  7. android开发环境安装记录

    首先进入http://developer.android.com/sdk/index.html, Google提供了一个新的DeveloperTools,即:ADT Bundle,中文翻译之:ADT捆 ...

  8. ORA-20000: ORU-10027: buffer overflow, limit of 10000 bytes

        要用dbms_output.put_line来输出语句,遇到以下错误: ERROR 位于第 1 行: ORA-20000: ORU-10027: buffer overflow, limit ...

  9. Windows Azure 网站 (WAWS) 中的服务器端包含 (SSI)

     编辑人员注释:本文章由 Windows Azure 网站团队的项目经理Erez Benari 撰写. Windows Azure 网站客户普遍关心的一个问题是关于我们对服务器端包含(Server ...

  10. C++模板:qsort

    void qsort(int l,int r){ int i,j,t,mid; mid=b[(l+r)>>1]; i=l; j=r; do{ while (b[i]<mid) i++ ...