每日一题(33) - 树的子结构

题目来自剑指offer

题目:

每日一题(33) - 树的子结构_第1张图片

举例:

每日一题(33) - 树的子结构_第2张图片

思路:

以先序的顺序对树进行处理,先比较子树的根值是否匹配,之后再比较其两个子树是否匹配

其实,这个方法类似字符串匹配的朴素方法,其实也可以先序遍历两个树,得到其先序遍历的序列,之后采用KMP算法匹配。

代码:

#include <iostream>
#include <assert.h>
using namespace std;

struct BinaryTreeNode
{
	char m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

/*
出口:
(1)模式树的根可以为空,表示某条路径上结点已经匹配结束,告诉上一层其孩子匹配
(2)模式树不为空,而主树为空时,表示不匹配
(3)模式树和主树都不为空,且其结点值有不同,直接返回不匹配
入口:
(4)模式树和主树都不为空,且其结点值都相同,继续匹配左右子树
返回值:
由于需要同时考虑左右子树,则在返回时需要同时左右子树返回的结果进行处理

*/
bool IsInclude(BinaryTreeNode* pRootTarget,BinaryTreeNode* pRootPattern)
{
	if (NULL == pRootPattern)//模式树为空,匹配成功
	{
		return true;
	}
	if (NULL == pRootTarget)//模式树不为空,主树为空,不匹配
	{
		return false;
	}
	if (pRootTarget->m_nValue != pRootPattern->m_nValue)
	{
		return false;
	}
	return IsInclude(pRootTarget->m_pLeft,pRootPattern->m_pLeft) 
		&& IsInclude(pRootTarget->m_pRight,pRootPattern->m_pRight); 
}

bool HasSubtree(BinaryTreeNode* pRootTarget,BinaryTreeNode* pRootPattern)
{
	bool bIsInclude = false;
	//边界条件
	if (NULL == pRootTarget || NULL == pRootPattern)//表示结点为NULL,表示某条路径遍历结束,均不匹配。
	{
		return false;
	}
	//判断根节点
	if (pRootTarget->m_nValue == pRootPattern->m_nValue)
	{
		bIsInclude =  IsInclude(pRootTarget,pRootPattern);
	}
	//判断左右子树是否匹配,但是在父亲已经匹配时,不用继续比较了
	if (!bIsInclude)
	{
		bIsInclude =  HasSubtree(pRootTarget->m_pLeft,pRootPattern);
	}
	if (!bIsInclude)
	{
		bIsInclude =  HasSubtree(pRootTarget->m_pRight,pRootPattern);
	}
	return bIsInclude;
}

void Create(BinaryTreeNode*& pRoot)  
{  
	char newData;  
	cin >> newData;  
	if ('#' == newData)  
	{  
		pRoot = NULL;  
	}  
	else  
	{  
		pRoot = new BinaryTreeNode;  
		pRoot->m_nValue = newData;  
		Create(pRoot->m_pLeft);  
		Create(pRoot->m_pRight);   
	}  
}  

void PreOrder(BinaryTreeNode* pRoot)
{
	if (pRoot)
	{
		cout<<pRoot->m_nValue<<" ";
		PreOrder(pRoot->m_pLeft);
		PreOrder(pRoot->m_pRight);
	}

}

int main()
{
	BinaryTreeNode* pRootTarget = NULL;
	BinaryTreeNode* pRootPattern = NULL;
	
	cout<<"Input First Tree A:"<<endl;
	Create(pRootTarget);//输入889##24##7##7##
	PreOrder(pRootTarget);
	cout<<endl;

	cout<<"Input First Tree B:"<<endl;
	Create(pRootPattern);//输入89##2##
	PreOrder(pRootPattern);
	cout<<endl;


	if (HasSubtree(pRootTarget,pRootPattern))
	{
		cout<<"树A包含树B!"<<endl;
	}
	else
	{
		cout<<"树A不包含树B!"<<endl;
	}

	system("pause");
	return 1;
}
注意:

上述代码使用先序建树,#表示结点没孩子了。

对于下图:

每日一题(33) - 树的子结构_第3张图片

左边的子树输入的序列:输入889##24##7##7##

右边的子树输入的序列:输入89##2##

你可能感兴趣的:(每日一题(33) - 树的子结构)