《剑指offer》:[18]如何判断树B是树A的子结构

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

和链表相比,树中的指针更多更复杂,所以需要格外的小心!

实例如下:

判断A树中是否包含B树。具体方法是先遍历A树,看A树中是否有B树的根结点。如果有再看该结点是否含有和B树一样的结构!如果没有特殊的要求,我们一般采用递归的方式实现。

《《剑指offer》:[18]如何判断树B是树A的子结构》

具体实现代码如下:

#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;
}

运行结果:

《《剑指offer》:[18]如何判断树B是树A的子结构》

由于二叉树相关的代码有大量的指针操作,每一次使用指针的时候,我们都要问自己这个指针有没有可能是NULL,如果是NULL该怎么处理。

    原文作者:B树
    原文地址: https://blog.csdn.net/gogokongyin/article/details/51601452
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞