判断一颗二叉树是否是另一颗树的子树

时间:2022-11-18 14:16:59
  • 题目:输入两棵二叉树A和B判断B是不是A的子树,二叉树节点定义如下
struct BinaryTree
{
BinaryTree(char data)
:_pLeft(NULL)
, _pRight(NULL)
, _data(data)
{}
BinaryTree *_pLeft;
BinaryTree *_pRight;
char _data;
};

附上创建树的代码,方便测试

void CreateBinaryTree(BinaryTree *&pRoot, char *str,size_t size, size_t &index)
{
if (index < size && str[index] != '#')
{
pRoot = new BinaryTree(str[index]);
CreateBinaryTree(pRoot->_pLeft, str, size, ++index);
CreateBinaryTree(pRoot->_pRight, str, size, ++index);
}
}

思路:可以分两步,第一步在在A中找和B的跟节点的值一样的结点R,第二步在判断A中以R为根节点的子树是不是包含和树B一样的结构。

  • 代码实现
bool IsSameSubTree(BinaryTree *pAroot, BinaryTree *pBroot)//判断相同根节点的子结构是否相同
{
if (NULL == pBroot)//B树为空了还没有返回证明A中有与B相等的子结构
return true;
if (NULL == pAroot)//A树为空了证明没有与B相同的子结构
return false;
if (pBroot->_data != pAroot->_data)//有节点不相等证明不是子结构
return false;
//相等继续判断其他节点
return (IsSameSubTree(pAroot->_pLeft, pBroot->_pLeft) && \
IsSameSubTree(pAroot->_pRight, pBroot->_pRight));
}
//判断B是否是A的子树
bool HassubTree(BinaryTree *pAroot,BinaryTree *pBroot)//寻找与B的根节点相同的结点
{
bool result = false;
if (NULL == pBroot || NULL == pAroot)
return result;
if (pBroot->_data == pAroot->_data)
result = IsSameSubTree(pAroot, pBroot);//判断相同结点的子结构是否相等
if (!result)//子结构不相等再继续寻找与B根节点相同的节点
result = HassubTree(pAroot->_pLeft, pBroot);
if (!result)
result = HassubTree(pAroot->_pRight, pBroot);
return result;
}
  • 测试用例
void subtreetest()
{
BinaryTree *pAroot;
BinaryTree *pBroot;
BinaryTree *pCroot;
char *astr = "aab##cd##e##e";
char *bstr = "ab##c";
char *cstr = "cd##f";
size_t index = 0;
CreateBinaryTree(pBroot, bstr, strlen(bstr), index);
index = 0;
CreateBinaryTree(pAroot, astr, strlen(astr), index);
bool ret = HassubTree(pAroot, pBroot);
cout << ret << endl;
index = 0;
CreateBinaryTree(pCroot, cstr, strlen(cstr), index);
ret = HassubTree(pAroot, pCroot);
cout << ret << endl;
}