题目:输入两棵二叉树A和B,判断B是不是A的子结构。
和链表相比,树中的指针更多更复杂,所以需要格外的小心!
实例如下:
判断A树中是否包含B树。具体方法是先遍历A树,看A树中是否有B树的根结点。如果有再看该结点是否含有和B树一样的结构!如果没有特殊的要求,我们一般采用递归的方式实现。
具体实现代码如下:
#include <iostream>
using namespace std;
struct Binarytree
{
int data;
Binarytree *pLeft;
Binarytree *pRight;
};
bool DoesTree1HasTree2(Binarytree *tree1,Binarytree *tree2);
void inserttree(Binarytree *tree,int value);
void CreateTree(Binarytree **tree,int *arr,int length);
void Preorder(Binarytree *tree);
void Destory(Binarytree *tree);
bool HasSubTree(Binarytree *tree1,Binarytree *tree2);
int arr1[7]={8,4,12,6,5,7,9};
int arr2[3]={6,5,7};
Binarytree *pRoot1=NULL;
Binarytree *pRoot2=NULL;
void inserttree(Binarytree *tree,int value)
{
//看是放在左边还是右边;
if(tree->data > value)//左边
{
if(NULL==tree->pLeft)
{
Binarytree *pNode=new Binarytree;
pNode->data=value;
pNode->pLeft=pNode->pRight=NULL;
tree->pLeft=pNode;
}
else
{
inserttree(tree->pLeft,value);
}
}
else
{
if(NULL==tree->pRight)
{
Binarytree *pNode=new Binarytree;
pNode->data=value;
pNode->pLeft=pNode->pRight=NULL;
tree->pRight=pNode;
}
else
{
inserttree(tree->pRight,value);
}
}
}
void CreateTree(Binarytree **tree,int *arr,int length)
{
for(int i=0;i<length;i++)
{
if(NULL==*tree)
{
Binarytree *pNode=new Binarytree;
pNode->data=arr[i];
pNode->pRight=pNode->pLeft=NULL;
*tree=pNode;
}
else
inserttree(*tree,arr[i]);
}
}
void Preorder(Binarytree *tree)
{
if(tree)
{
cout<<tree->data<<" ";
Preorder(tree->pLeft);
Preorder(tree->pRight);
}
}
void Destory(Binarytree *tree)
{
if(NULL==tree)
return ;
else
{
Destory(tree->pLeft);
Destory(tree->pRight);
delete tree;
tree=NULL;
}
}
bool HasSubTree(Binarytree *tree1,Binarytree *tree2) //是否存在子树的根结点;
{
bool result=false;
if(NULL!=tree1 && NULL !=tree2)
{
if(tree1->data == tree2->data)
result=DoesTree1HasTree2(tree1,tree2);
if(!result)
result=HasSubTree(tree1->pLeft,tree2);
if(!result)
result=HasSubTree(tree1->pRight,tree2);
}
return result;
}
bool DoesTree1HasTree2(Binarytree *tree1,Binarytree *tree2)
{
if(NULL==tree2)
return true;
if(NULL==tree1)
return false;
if(tree1->data!= tree2->data)
return false;
return DoesTree1HasTree2(tree1->pLeft,tree2->pLeft) && DoesTree1HasTree2(tree1->pRight,tree2->pRight);
}
int main()
{
CreateTree(&pRoot1,arr1,7);
CreateTree(&pRoot2,arr2,3);
Preorder(pRoot1);
cout<<endl;
Preorder(pRoot2);
cout<<endl;
if(HasSubTree(pRoot1,pRoot2))
cout<<"TREE1 HAS TREE2!"<<endl;
else
cout<<"TREE1 HAS'T TREE2!"<<endl;
Destory(pRoot1);
Destory(pRoot2);
system("pause");
return 0;
}
运行结果:
由于二叉树相关的代码有大量的指针操作,每一次使用指针的时候,我们都要问自己这个指针有没有可能是NULL,如果是NULL该怎么处理。