在准备Amazon的面试,有一道题目是这样的。
已知两个树A,B,求B是否是A的子树。
其实题目并不难。不知道为什么我就把自己困在建树上了。我记得我上一次写二叉树也是把自己困在建树上了。其实遍历什么的都很清晰。我也不记得我两年前是怎么建树的了,这次重新写了一个。
不知道在哪里看的实例输入里面有0,从此0在我脑海里面根深蒂固。我的输入还蛮奇怪的。仔细想想其实还是不把0纳入考虑,因为会影响结果。不过懒得改了。。。建树建成我这样也是。。。
先看重点的好了,参考了网上现有的很多博客。我已经不记得当时看到的是哪个了。
思路很清晰:
public boolean HasSubTree(Node root1, Node root2) {
// TODO Auto-generated method stub
boolean result = false;
if(root1 != null && root2 != null)//排除特殊根不存在的特殊情况
{
if(root1.val == root2.val)//如果两个根一样,测试
{
result = DoesTree1HasTree2(root1,root2);
}
}
if(result!=true)
{
result = DoesTree1HasTree2(root1.left,root2);
}
if(result!=true)
{
result = DoesTree1HasTree2(root1.right,root2);
}
return result;
}
private boolean DoesTree1HasTree2(Node root1, Node root2) {
// TODO Auto-generated method stub
boolean lflag = false;
boolean rflag = false;
if(root2 == null)
return true;//测试到树B结尾了,搞定
if(root1 == null)
return false;//测到树A结尾了,没有办法继续,B一定不是A子树
if(root1.val != root2.val)
{
return false;//最后不同
}else
{
lflag = DoesTree1HasTree2(root1.left,root2.left);
rflag = DoesTree1HasTree2(root1.right, root2.right);
return lflag&&rflag;
}
}
主函数:
package Tree;
import Tree.BinaryTree.Node;
public class HasSubtree {
/*
* 输入两棵树A和B,判断B是不是A的子树
*/
public static void main(String[] args){
System.out.println("============================= Tree 1 ==========================================");
/*
* 1
* / \
* 2 3
* / \ / \
* 4 5 0 6
* / \ / \
* 0 0 7 0
/\
0 0
*/
int[] data01 = {1,2,4,0,0,5,7,0,0,0,3,0,6};
BinaryTree bTree = new BinaryTree();
bTree.root = bTree.buildTree(bTree.root,data01);
bTree.PreOrderTraverse(bTree.root);
System.out.println("============================= Tree 2 ==========================================");
int[] data02 = {2,4,0,0,5};
BinaryTree bTree2 = new BinaryTree();
bTree2.root = bTree2.buildTree(bTree2.root,data02);
bTree2.PreOrderTraverse(bTree2.root);
boolean flag = false;
flag = bTree.HasSubTree(bTree.root,bTree2.root);
System.out.println("=======================================\n"+flag);
}
}
二叉树部分:
package Tree;
import java.util.Stack;
import Tree.BinaryTree.Node;
public class BinaryTree {
Node root;
Node parent = null;
public static class Node{
int val;
Node left;
Node right;
public Node(int val)
{
this.left = null;
this.right = null;
this.val = val;
}
}
public BinaryTree()
{
root = null;
}
public Node buildTree(Node root, int[] data) {
// TODO Auto-generated method stub
int i=0;
Node nowNode= null;
Node LastNode = null;
if(root == null)
{
root = new Node(data[i]);
nowNode = root;
LastNode = root;
i++;
}
while(i < data.length)
{
// System.out.println("while: i:"+i+" 要存入的是: "+data[i]+" 叶子节点是: "+nowNode.val);
if(nowNode.val == 0)
{
if(LastNode.right == null)
{
Node node = new Node(data[i]);
LastNode.right = node;
nowNode = LastNode.right;
i++;
parent = null;
nowNode = FindParentsNode(root,LastNode);
}else
{
// System.out.println("Last: "+LastNode.val +"\tNow : "+nowNode.val);
while(nowNode!=null)
{
parent = null;
if(nowNode.right!=null)
{
LastNode = nowNode;
parent = null;
nowNode = FindParentsNode(root,LastNode);
}else
{
// System.out.println("Out of Bounds:\t"+i);
Node node = new Node(data[i]);
LastNode = nowNode;
nowNode.right = node;
nowNode = nowNode.right;
i++;
break;
}
}
}
}else
{
if(nowNode.left == null)
{
//
Node node = new Node(data[i]);
nowNode.left = node;
LastNode = nowNode;
nowNode = nowNode.left;
// System.out.println("i:"+i+"要存入的是: "+data[i]+" 叶子节点是: "+nowNode.val);
i++;
}
else
{
Node node = new Node(data[i]);
nowNode.right = node;
LastNode = nowNode;
nowNode =nowNode.right;
i++;
}
}
}
return root;
}
private Node FindParentsNode(Node root2, Node node) {
// TODO Auto-generated method stub
Node p = root2;
if(p != null)
{
// System.out.println(p.val);
if(p.left!=null)
if(p.left.val == node.val)
parent = p;
if(p.right!=null)
if(p.right.val == node.val)
parent = p;
FindParentsNode(p.left,node);
FindParentsNode(p.right,node);
}else
return parent;
return parent;
}
void PreOrderTraverse(Node root) {
// TODO Auto-generated method stub
Node p = root;
if(p != null)
{
System.out.println(p.val);
PreOrderTraverse(p.left);
PreOrderTraverse(p.right);
}else
return;
}
public boolean HasSubTree(Node root1, Node root2) {
// TODO Auto-generated method stub
boolean result = false;
if(root1 != null && root2 != null)
{
if(root1.val == root2.val)
{
result = DoesTree1HasTree2(root1,root2);
}
}
if(result!=true)
{
result = DoesTree1HasTree2(root1.left,root2);
}
if(result!=true)
{
result = DoesTree1HasTree2(root1.right,root2);
}
return result;
}
private boolean DoesTree1HasTree2(Node root1, Node root2) {
// TODO Auto-generated method stub
boolean lflag = false;
boolean rflag = false;
if(root2 == null)
return true;//测试到树B结尾了,搞定
if(root1 == null)
return false;//测到树A结尾了,没有办法继续,B一定不是A子树
if(root1.val != root2.val)
{
return false;//最后不同
}else
{
lflag = DoesTree1HasTree2(root1.left,root2.left);
rflag = DoesTree1HasTree2(root1.right, root2.right);
return lflag&&rflag;
}
}
}