剑指Offer----面试题18:树的子结构

题目:


输入两颗二叉树A和B,判断B是不是A的子结构。如下图:树B是树A的子结构。


方法一:


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


源代码如下:

#include"BinaryTree.h"
#include<iostream>

using std::cout;
using std::endl;

using namespace OrdinaryBinaryTreeSpace2;

bool Total(BinaryTreeNode *root1, BinaryTreeNode *root2);
bool HasSubTree(BinaryTreeNode *root1, BinaryTreeNode *root2);
bool DoesTreeOneHaveTreeTwo(BinaryTreeNode *root1, BinaryTreeNode *root2);

bool Total(BinaryTreeNode *root1, BinaryTreeNode *root2)
{
	if (root1 == NULL && root2 != NULL)
		return false;
	else if (root1 == NULL && root2 == NULL)
		return false;
	else if (root1 != NULL && root2 == NULL)
		return true;

	return HasSubTree(root1, root2);
}

bool HasSubTree(BinaryTreeNode *root1, BinaryTreeNode *root2)
{
	bool result = false;

	if (root1 != NULL && root2 != NULL)
	{
		if (root1->element == root2->element)
			result = DoesTreeOneHaveTreeTwo(root1, root2);
		if (!result)
			result = HasSubTree(root1->left, root2);
		if (!result)
			result = HasSubTree(root1->right, root2);
	}

	return result;
}

bool DoesTreeOneHaveTreeTwo(BinaryTreeNode *root1, BinaryTreeNode *root2)
{
	if (root2 == NULL)
		return true;

	if (root1 == NULL)
		return false;

	if (root1->element != root2->element)
		return false;

	return DoesTreeOneHaveTreeTwo(root1->left, root2->left) && DoesTreeOneHaveTreeTwo(root1->right, root2->right);
}

void test11()
{
	cout << "\t===========树A含有树B============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(7);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);
	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, node4, node5);
	ConnectBinaryTreeNodes(node3, NULL, NULL);
	ConnectBinaryTreeNodes(node4, NULL, NULL);
	ConnectBinaryTreeNodes(node5, node6, node7);
	ConnectBinaryTreeNodes(node6, NULL, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	BinaryTreeNode *node21 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node22 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node23 = CreateBinaryTreeNode(2);
	ConnectBinaryTreeNodes(node21, node22, node23);
	ConnectBinaryTreeNodes(node22, NULL, NULL);
	ConnectBinaryTreeNodes(node23, NULL, NULL);

	bool result = Total(node1, node21);

	if (result)
		cout << "Tree A contains tree B" << endl;
	else
		cout << "Tree A not contains tree B" << endl;
}

void test12()
{
	cout << "\t===========树A不含有树B============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(7);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);
	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, node4, node5);
	ConnectBinaryTreeNodes(node3, NULL, NULL);
	ConnectBinaryTreeNodes(node4, NULL, NULL);
	ConnectBinaryTreeNodes(node5, node6, node7);
	ConnectBinaryTreeNodes(node6, NULL, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	BinaryTreeNode *node21 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node22 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node23 = CreateBinaryTreeNode(3);
	ConnectBinaryTreeNodes(node21, node22, node23);
	ConnectBinaryTreeNodes(node22, NULL, NULL);
	ConnectBinaryTreeNodes(node23, NULL, NULL);

	bool result = Total(node1, node21);

	if (result)
		cout << "Tree A contains tree B" << endl;
	else
		cout << "Tree A not contains tree B" << endl;
}

void test13()
{
	cout << "\t===========树A非空,树B为空============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(7);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);
	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, node4, node5);
	ConnectBinaryTreeNodes(node3, NULL, NULL);
	ConnectBinaryTreeNodes(node4, NULL, NULL);
	ConnectBinaryTreeNodes(node5, node6, node7);
	ConnectBinaryTreeNodes(node6, NULL, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	bool result = Total(node1, NULL);

	if (result)
		cout << "Tree A contains tree B" << endl;
	else
		cout << "Tree A not contains tree B" << endl;
}

void test14()
{
	cout << "\t===========树A为空,树B非空============" << endl;
	BinaryTreeNode *node21 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node22 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node23 = CreateBinaryTreeNode(3);
	ConnectBinaryTreeNodes(node21, node22, node23);
	ConnectBinaryTreeNodes(node22, NULL, NULL);
	ConnectBinaryTreeNodes(node23, NULL, NULL);

	bool result = Total(NULL, node21);

	if (result)
		cout << "Tree A contains tree B" << endl;
	else
		cout << "Tree A not contains tree B" << endl;
}

void test15()
{
	cout << "\t===========树A树B都为空============" << endl;
	bool result = Total(NULL, NULL);

	if (result)
		cout << "Tree A contains tree B" << endl;
	else
		cout << "Tree A not contains tree B" << endl;
}

int main()
{
	test11();
	test12();
	test13();
	test14();
	test15();

	system("pause");
	return 0;
}

运行结果:
        ===========树A含有树B============
Tree A contains tree B
        ===========树A不含有树B============
Tree A not contains tree B
        ===========树A非空,树B为空============
Tree A contains tree B
        ===========树A为空,树B非空============
Tree A not contains tree B
        ===========树A树B都为空============
Tree A not contains tree B
请按任意键继续. . .


官方源代码:

#include"BinaryTree.h"
#include<cstdio>
#include<cstdlib>

using namespace OrdinaryBinaryTreeSpace2;

bool HasSubtreeCore(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);

bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
	bool result = false;

	if (pRoot1 != NULL && pRoot2 != NULL)
	{
		if (pRoot1->element == pRoot2->element)
			result = DoesTree1HaveTree2(pRoot1, pRoot2);
		if (!result)
			result = HasSubtree(pRoot1->left, pRoot2);
		if (!result)
			result = HasSubtree(pRoot1->right, pRoot2);
	}

	return result;
}

bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
	if (pRoot2 == NULL)
		return true;

	if (pRoot1 == NULL)
		return false;

	if (pRoot1->element != pRoot2->element)
		return false;

	return DoesTree1HaveTree2(pRoot1->left, pRoot2->left) &&
		DoesTree1HaveTree2(pRoot1->right, pRoot2->right);
}

// ====================测试代码====================
void Test(char* testName, BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2, bool expected)
{
	if (HasSubtree(pRoot1, pRoot2) == expected)
		printf("%s passed.\n", testName);
	else
		printf("%s failed.\n", testName);
}

// 树中结点含有分叉,树B是树A的子结构
//                  8                8
//              /       \           / \
//             8         7         9   2
//           /   \
//          9     2
//               / \
//              4   7
void Test1()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(2);
	BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4);
	BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7);

	ConnectBinaryTreeNodes(pNodeA1, pNodeA2, pNodeA3);
	ConnectBinaryTreeNodes(pNodeA2, pNodeA4, pNodeA5);
	ConnectBinaryTreeNodes(pNodeA5, pNodeA6, pNodeA7);

	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeB1, pNodeB2, pNodeB3);

	Test("Test1", pNodeA1, pNodeB1, true);

	DestoryTree(pNodeA1);
	DestoryTree(pNodeB1);
}

// 树中结点含有分叉,树B不是树A的子结构
//                  8                8
//              /       \           / \
//             8         7         9   2
//           /   \
//          9     3
//               / \
//              4   7
void Test2()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(3);
	BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4);
	BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7);

	ConnectBinaryTreeNodes(pNodeA1, pNodeA2, pNodeA3);
	ConnectBinaryTreeNodes(pNodeA2, pNodeA4, pNodeA5);
	ConnectBinaryTreeNodes(pNodeA5, pNodeA6, pNodeA7);

	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeB1, pNodeB2, pNodeB3);

	Test("Test2", pNodeA1, pNodeB1, false);

	DestoryTree(pNodeA1);
	DestoryTree(pNodeB1);
}

// 树中结点只有左子结点,树B是树A的子结构
//                8                  8
//              /                   / 
//             8                   9   
//           /                    /
//          9                    2
//         /      
//        2        
//       /
//      5
void Test3()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
	BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

	ConnectBinaryTreeNodes(pNodeA1, pNodeA2, NULL);
	ConnectBinaryTreeNodes(pNodeA2, pNodeA3, NULL);
	ConnectBinaryTreeNodes(pNodeA3, pNodeA4, NULL);
	ConnectBinaryTreeNodes(pNodeA4, pNodeA5, NULL);

	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeB1, pNodeB2, NULL);
	ConnectBinaryTreeNodes(pNodeB2, pNodeB3, NULL);

	Test("Test3", pNodeA1, pNodeB1, true);

	DestoryTree(pNodeA1);
	DestoryTree(pNodeB1);
}

// 树中结点只有左子结点,树B不是树A的子结构
//                8                  8
//              /                   / 
//             8                   9   
//           /                    /
//          9                    3
//         /      
//        2        
//       /
//      5
void Test4()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
	BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

	ConnectBinaryTreeNodes(pNodeA1, pNodeA2, NULL);
	ConnectBinaryTreeNodes(pNodeA2, pNodeA3, NULL);
	ConnectBinaryTreeNodes(pNodeA3, pNodeA4, NULL);
	ConnectBinaryTreeNodes(pNodeA4, pNodeA5, NULL);

	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);

	ConnectBinaryTreeNodes(pNodeB1, pNodeB2, NULL);
	ConnectBinaryTreeNodes(pNodeB2, pNodeB3, NULL);

	Test("Test4", pNodeA1, pNodeB1, false);

	DestoryTree(pNodeA1);
	DestoryTree(pNodeB1);
}

// 树中结点只有右子结点,树B是树A的子结构
//       8                   8
//        \                   \ 
//         8                   9   
//          \                   \
//           9                   2
//            \      
//             2        
//              \
//               5
void Test5()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
	BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

	ConnectBinaryTreeNodes(pNodeA1, NULL, pNodeA2);
	ConnectBinaryTreeNodes(pNodeA2, NULL, pNodeA3);
	ConnectBinaryTreeNodes(pNodeA3, NULL, pNodeA4);
	ConnectBinaryTreeNodes(pNodeA4, NULL, pNodeA5);

	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeB1, NULL, pNodeB2);
	ConnectBinaryTreeNodes(pNodeB2, NULL, pNodeB3);

	Test("Test5", pNodeA1, pNodeB1, true);

	DestoryTree(pNodeA1);
	DestoryTree(pNodeB1);
}

// 树A中结点只有右子结点,树B不是树A的子结构
//       8                   8
//        \                   \ 
//         8                   9   
//          \                 / \
//           9               3   2
//            \      
//             2        
//              \
//               5
void Test6()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
	BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

	ConnectBinaryTreeNodes(pNodeA1, NULL, pNodeA2);
	ConnectBinaryTreeNodes(pNodeA2, NULL, pNodeA3);
	ConnectBinaryTreeNodes(pNodeA3, NULL, pNodeA4);
	ConnectBinaryTreeNodes(pNodeA4, NULL, pNodeA5);

	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);
	BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeB1, NULL, pNodeB2);
	ConnectBinaryTreeNodes(pNodeB2, pNodeB3, pNodeB4);

	Test("Test6", pNodeA1, pNodeB1, false);

	DestoryTree(pNodeA1);
	DestoryTree(pNodeB1);
}

// 树A为空树
void Test7()
{
	BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);
	BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeB1, NULL, pNodeB2);
	ConnectBinaryTreeNodes(pNodeB2, pNodeB3, pNodeB4);

	Test("Test7", NULL, pNodeB1, false);

	DestoryTree(pNodeB1);
}

// 树B为空树
void Test8()
{
	BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(3);
	BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);

	ConnectBinaryTreeNodes(pNodeA1, NULL, pNodeA2);
	ConnectBinaryTreeNodes(pNodeA2, pNodeA3, pNodeA4);

	Test("Test8", pNodeA1, NULL, false);

	DestoryTree(pNodeA1);
}

// 树A和树B都为空
void Test9()
{
	Test("Test9", NULL, NULL, false);
}

int main()
{
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	Test6();
	Test7();
	Test8();
	Test9();

	system("pause");
	return 0;
}

运行结果:
Test1 passed.
Test2 passed.
Test3 passed.
Test4 passed.
Test5 passed.
Test6 passed.
Test7 passed.
Test8 passed.
Test9 passed.
请按任意键继续. . .



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值