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

本文探讨如何判断一棵二叉树是否为另一棵二叉树的子结构,涉及树的遍历和比较方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

算法思想:可分为两步,第一步:在树A中查找是否具有和树B的根节点的值一样的结点;(实际上就是树的遍历)
                                        第二步:再判断树A中以该结点为根节点的子树是不是包含和树B一样的结构。
代码实现:
#include 
using namespace std;

template 
struct BinaryTreeNode
{
	BinaryTreeNode* _left;
	BinaryTreeNode* _right;
	T _data;

	BinaryTreeNode(const T& x)
		:_left(NULL)
		, _right(NULL)
		,_data(x)
	{}
};

template 
class BinaryTree
{
	typedef BinaryTreeNode Node;
public:
	BinaryTree()
		:_root(NULL)
	{}

	~BinaryTree()
	{
		Destroy(_root);
	}

	void Destroy(Node* root)
	{
		if (root == NULL)
			return;
		Destroy(root->_left);
		Destroy(root->_right);
		delete root;
	}

	BinaryTree(T* a, size_t n, const T& invalid)
	{
		size_t index = 0;
		_root = _CreateTree(a, n, invalid, index);
	}

	Node* Find(const T& x)                 //判断一个节点是否在一棵二叉树中
	{
		return _Find(_root, x);
	}

	bool HaveTree(BinaryTree& s1, BinaryTree& s2)
	{
		return _HaveTree(s1._root, s2._root);
	}

	bool DoeshaveTree2InTree1(Node* root1, Node* root2)
	{
		if (root2 == NULL)         //若B树为空,则空树仍为A的子结构
			return true;
		if (root1 == NULL)         //若A树为空,则树B不是A的子结构
			return false;

		if (root1->_data != root2->_data)
			return false;
		return DoeshaveTree2InTree1(root1->_left, root2->_left)      //若找到A与B树的根节点的值相同的节点,则再看相同节点的左右孩子的值是否一致
			&& DoeshaveTree2InTree1(root1->_right, root2->_right);
	}



protected:
	Node* _CreateTree(T* a, size_t n, const T& invalid, size_t& index)
	{
		Node* root = NULL;
		if (index < n && a[index] != invalid)
		{
			root = new Node(a[index]);
			root->_left = _CreateTree(a, n, invalid, ++index);
			root->_right = _CreateTree(a, n, invalid, ++index);

		}
		return root;
	}

	Node* _Find(Node* root, const T& x)
	{
		if (root == NULL)
			return NULL;
		if (root->_data == x)
			return root;
		Node* ret = _Find(root->_left, x);
		if (ret)
			return ret;
		return _Find(root->_right, x);

	}
	bool _HaveTree(Node* root1, Node* root2)
	{
		bool result = false;

		if (root1 != NULL && root2 != NULL)
		{
			if (root1->_data == root2->_data)
				result = DoeshaveTree2InTree1(root1, root2);
			if (!result)
				result = _HaveTree(root1->_left, root2);       //若A的根节点的值与B树的根节点的值不一致,则遍历A树找是否具有和其相同的节点
			if (!result)
				result = _HaveTree(root1->_right, root2);
		}
		return result;
	}
protected:
	Node* _root;
};


void Test()
{
	int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
	int b[] = { 2, 3,'#','#', 4 };
	BinaryTree s(a, sizeof(a) / sizeof(a[0]), '#');
	BinaryTree s1(b, sizeof(b) / sizeof(b[0]), '#');
	BinaryTreeNode* tmp = s.Find(4);
	if (tmp)
	{
		cout << "找到了:" << tmp->_data << endl;
	}
	else
	{
		cout << "没找到" << endl;
	}

	BinaryTree ret;
	cout << ret.HaveTree(s, s1) << endl;
}


测试结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值