剑指offer面试题18:树的子结构

题目:输入两棵二叉树A和B,判断B是不是A的子结构。
算法分析:


         要查找树A中是否存在和树B结构一样的子树,我们可以分为两步,第一步:在树A中找到和树B的根节点的值一样的节点R,第二步再判断树A中以R为根节点的子树是不是包含和树B一样的结构。
以上面两棵树为例来详细分析这个过程。首先我们试着在树A中找到值为8(树B的根节点的值)得节点。从树A的根节点开始遍历,我们发现它的根节点的值就是8.接着我们就去判断树A的根节点线面的子树是不是含有和树B一样的结构。在树A中,根节点的左子节点的值是8,而树B的根节点的左子节点是9,对应的两个节点不同。
因此我们仍然需要遍历树A,接着查找值为8的节点。我们在树的第二层找到了一个值为8的节点,然后进行第二步判断,即判断这个节点下面的子树是否含有和树B一样结构的子树。于是我们遍历这个节点下面的子树,先后得到两个子节点9和2,这和树B的结构完全相同。此时我们在树A中找到了一个和树B的结构一样的子树,因此树B是树A的子结构。



程序代码:

/**************************************************************      
* Copyright (c) 2016, 
* All rights reserved.                   
* 版 本 号:v1.0                   
* 题目描述:树的子结构
* 		       题目:输入一个二叉树A和B,判断B是不是A的子结构。
* 输入描述:
* 程序输出: 
* 问题分析: 
* 算法描述:要查找树A中是否存在和树B结构一样的子树,我们可以分为两步:第一步:在树A中找到和树B的根节点的值一样的节点R,
* 			第二步再判断树A中以R为根节点的子树是不是包含和树B一样的结构。以上面两棵树为例来详细分析这个过程。
* 			首先我们试着在树A中找到值为8(树B的根节点的值)得节点。从树A的根节点开始遍历,我们发现它的根节点的值就是8.
* 			接着我们就去判断树A的根节点线面的子树是不是含有和树B一样的结构。在树A中,根节点的左子节点的值是8,而树B的根节点的左子节点是9,
* 			对应的两个节点不同。因此我们仍然需要遍历树A,接着查找值为8的节点。我们在树的第二层找到了一个值为8的节点,
* 			然后进行第二步判断,即判断这个节点下面的子树是否含有和树B一样结构的子树。于是我们遍历这个节点下面的子树,
* 			先后得到两个子节点9和2,这和树B的结构完全相同。此时我们在树A中找到了一个和树B的结构一样的子树,因此树B是树A的子结构。
* 完成日期:2016-09-01
***************************************************************/ 

package org.marsguo.offerproject;

 class TreeNode{
	int val = 0;
	TreeNode left = null;
	TreeNode right = null;
	public TreeNode(int val){
		this.val = val;
	}
}

 class Solution{
	public boolean HasSubtree(TreeNode root1,TreeNode root2){
		boolean result =false;
		/*当Tree1和Tree2都不为0时才进行比较,否则直接返回false*/
		if(root1 != null && root2 != null){
			if(root1.val == root2.val){						//如果找到了对应Tree2根节点的节点
				result = DoesTreeHaveTree2(root1,root2);	//以这个根节点为起点判断是否包含Tree2
			}
			if(!result){									//如果没有找到,则去root的左子节点当做起点,去判断是否包含Tree2
				result = HasSubtree(root1.left, root2);
			}
			if(!result){									//如果没有找到,则去root的右子节点当做起点,去判断是否包含Tree2
				result = HasSubtree(root1.right,root2);
			}
		}
		return result;										//返回结果
	}
	public boolean DoesTreeHaveTree2(TreeNode root1,TreeNode root2){
		if(root2 == null){									//如果Tree2已经遍历完了都能对应的上,返回true
			return true;
		}
		if(root1 == null && root2 != null){					//如果Tree1已经遍历完了Tree2却没有遍历完,返回false
			return false;
		}
		if(root1.val != root2.val) {						//如果其中一个节点没有对应上,返回false
			return false;
		}
		/*如果根节点对应上了,那么就分别去子节点里匹配*/
		return DoesTreeHaveTree2(root1.left, root2.left)&&DoesTreeHaveTree2(root1.right, root2.right);
	}
}

public class HasSubTree {
	public static void main(String[] args){
		 /*  
		        1   
		       / \   
		      2   3   
		     / \   \   
		    4   5   6       
		  */    
		TreeNode r1 = new TreeNode(1);
		TreeNode r2 = new TreeNode(2);
		TreeNode r3 = new TreeNode(3);
		TreeNode r4 = new TreeNode(4);
		TreeNode r5 = new TreeNode(5);
		TreeNode r6 = new TreeNode(6);

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值