剑指Offer(Java版):树的子结构
2016-07-21 00:00
351 查看
二叉树的结构定义为:
[java] view plain copy
package utils;
public class BinaryTreeNode {
public int value;
public BinaryTreeNode leftNode;
public BinaryTreeNode rightNode;
public BinaryTreeNode(){
}
public BinaryTreeNode(int value){
this.value = value ;
this.leftNode = null;
this.rightNode = null;
}
}
或者
class BinaryTreeNode{
int data;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
}
题目:输入两棵二叉树A和B,判断B是不是A的子结构。
例如图中所示的两棵二叉树,由于A中有一部分子树的结构和B 是一样的,因此B是A的子结构。
要查找树A中是否存在和树B结构一样的子树,我们可以分两步:第一步在树A中找到和B的根节点的值一样的结点R,第二步再判断树A中以R为根结点的子树是不是包含和树B一样的结构。
以上面的两棵树为例来详细分析这个过程。首先我们试着在树A中找到值 为8的结点。从树A的根节点开始遍历,我们发现它的根节点的值就是8.接着我们就去判断树A的根节点下面的子树是不是含有和树B一样的结构。在树A中,根 节点的左子结点的值是8,而树B的根节点的左子结点是9,对应的两个结点不同。
因此我们仍然要遍历A,接着查找值为8的结点。我们在树的第二层中找 到一个值为8 的结点,然后进行第二步的判断,即判断这个结点下面的子树是否含有和树B一样结构的子树。于是我们遍历这个结点下面的子树,先后得到两个子节点9和2,这 和树B的结构完全相同。此时我们在树A中找到了一个和树B的结构一样的子树,因此树B和树A的子结构。
在面试的时候,我们一定要检查边界条件,即检查空指针。当树A或树B为空的时候,定义相同的输出。如果没有检查并做响应的处理,程序非常容易崩溃,这是面试的时候非常忌讳的事情。
下面我们用Java代码来实现:
package cglib;
class BinaryTreeNode{
int data;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
}
public class DeleteNode {
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;
DeleteNode test=new DeleteNode();
System.out.println(test.hasSubTree(root1, root2));
}
public boolean hasSubTree(BinaryTreeNode root1,BinaryTreeNode root2){
boolean result=false;
if(root1!=null&&root2!=null){
if(root1.data==root2.data){//8,8
result=doesTree1HavaTree2(root1,root2);
if(!result)
result=hasSubTree(root1.leftNode, root2);//看左结点8是不是等于头结点8
if(!result)
result=hasSubTree(root1.rightNode, root2);
}
}
return result;//8,9不等
}
private boolean doesTree1HavaTree2(BinaryTreeNode root1, BinaryTreeNode root2) {
if(root2==null){
return true;
}
else if(root1==null)
return false;
if(root1.data!=root2.data){
return false;
}
return doesTree1HavaTree2(root1.leftNode, root2.leftNode)&&
doesTree1HavaTree2(root1.rightNode, root2.rightNode);//头结点相等,继续看左右两结点是不是相等
}
}
[java] view plain copy
package utils;
public class BinaryTreeNode {
public int value;
public BinaryTreeNode leftNode;
public BinaryTreeNode rightNode;
public BinaryTreeNode(){
}
public BinaryTreeNode(int value){
this.value = value ;
this.leftNode = null;
this.rightNode = null;
}
}
或者
class BinaryTreeNode{
int data;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
}
题目:输入两棵二叉树A和B,判断B是不是A的子结构。
例如图中所示的两棵二叉树,由于A中有一部分子树的结构和B 是一样的,因此B是A的子结构。
要查找树A中是否存在和树B结构一样的子树,我们可以分两步:第一步在树A中找到和B的根节点的值一样的结点R,第二步再判断树A中以R为根结点的子树是不是包含和树B一样的结构。
以上面的两棵树为例来详细分析这个过程。首先我们试着在树A中找到值 为8的结点。从树A的根节点开始遍历,我们发现它的根节点的值就是8.接着我们就去判断树A的根节点下面的子树是不是含有和树B一样的结构。在树A中,根 节点的左子结点的值是8,而树B的根节点的左子结点是9,对应的两个结点不同。
因此我们仍然要遍历A,接着查找值为8的结点。我们在树的第二层中找 到一个值为8 的结点,然后进行第二步的判断,即判断这个结点下面的子树是否含有和树B一样结构的子树。于是我们遍历这个结点下面的子树,先后得到两个子节点9和2,这 和树B的结构完全相同。此时我们在树A中找到了一个和树B的结构一样的子树,因此树B和树A的子结构。
在面试的时候,我们一定要检查边界条件,即检查空指针。当树A或树B为空的时候,定义相同的输出。如果没有检查并做响应的处理,程序非常容易崩溃,这是面试的时候非常忌讳的事情。
下面我们用Java代码来实现:
package cglib;
class BinaryTreeNode{
int data;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
}
public class DeleteNode {
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;
DeleteNode test=new DeleteNode();
System.out.println(test.hasSubTree(root1, root2));
}
public boolean hasSubTree(BinaryTreeNode root1,BinaryTreeNode root2){
boolean result=false;
if(root1!=null&&root2!=null){
if(root1.data==root2.data){//8,8
result=doesTree1HavaTree2(root1,root2);
if(!result)
result=hasSubTree(root1.leftNode, root2);//看左结点8是不是等于头结点8
if(!result)
result=hasSubTree(root1.rightNode, root2);
}
}
return result;//8,9不等
}
private boolean doesTree1HavaTree2(BinaryTreeNode root1, BinaryTreeNode root2) {
if(root2==null){
return true;
}
else if(root1==null)
return false;
if(root1.data!=root2.data){
return false;
}
return doesTree1HavaTree2(root1.leftNode, root2.leftNode)&&
doesTree1HavaTree2(root1.rightNode, root2.rightNode);//头结点相等,继续看左右两结点是不是相等
}
}
相关文章推荐
- 剑指Offer(Java版):二叉树的镜像
- 剑指Offer(Java版):顺时针打印矩阵
- js各类正则表达式(中文、字母、数字、全角)
- JavaScript 函数replace揭秘
- JavaScript 正则表达式上——基本语法
- js数组去重的4个方法及ts数组去重
- JQuery 时间倒计时
- nodejs推荐ide
- HTML文件中引入js文件路径
- JS触发a标签的跳转事件
- JS 实现一次下载多个文件
- jquery 关于event.target使用的几点说明介绍
- LeetCode进阶之路(Remove Nth Node From End of List)
- EXTJS4.0.7开发积累(9)
- angularJS 服务三
- 《JavaScript高级程序设计》笔记系列2-- 基本概念1
- Bootstrap入门基础
- jQuery.each的function中有哪些参数(可以大概理解function中的参数问题)
- 带你从零了解BootStrap
- Bootstrap表单布局详解