面试题18树的子结构

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


方法一:


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

#include<iostream>
using namespace std;
struct BinaryTreeNode
{
	int _val;
	BinaryTreeNode* _left;
	BinaryTreeNode* _right;
};

BinaryTreeNode* CreateBinaryTreeNode(int val)
{
	BinaryTreeNode* Node=new BinaryTreeNode();
	Node->_val=val;
	Node->_right=NULL;
	Node->_left=NULL;
	return Node;
}
void ConnectTreeNodes(BinaryTreeNode* parent,BinaryTreeNode* left,BinaryTreeNode* right)
{
	if(parent!=NULL)
	{
		parent->_left=left;
		parent->_right=right;
	}
}
void PrintTreeNode(BinaryTreeNode* Node)
{
	if(Node!=NULL)
	{
		printf("val of this node:%d\n",Node->_val);
		if(Node->_left!=NULL)
			printf("val of its left child is:%d\n",Node->_left->_val);
		else
			printf("its left child is null\n");
		if(Node->_right!=NULL)
		    printf("val of its right child is:%d\n",Node->_right->_val);
		else
			printf("its right child is null\n");
	}
	else
	{
		printf("this node is null\n");
	}
}
void PrintTree(BinaryTreeNode* Root)
{
	PrintTreeNode(Root);
	if(Root!=NULL)
	{
		if(Root->_left!=NULL)
			PrintTree(Root->_left);
		if(Root->_right!=NULL)
			PrintTree(Root->_right);
	}
}
void DestroyTree(BinaryTreeNode* Root)
{
	if(Root!=NULL)
	{
		BinaryTreeNode* left=Root->_left;
		BinaryTreeNode* right=Root->_right;
		delete Root;
		Root=NULL;
		DestroyTree(left);
		DestroyTree(right);
	}
}
bool DoesTree1HaveTree2(BinaryTreeNode* Root1, BinaryTreeNode* Root2)  
{  
    if(Root2 == NULL)  
        return true;  
  
    if(Root1 == NULL)  
        return false;  
  
    if(Root1->_val != Root2->_val)  
        return false;  
  
    return DoesTree1HaveTree2(Root1->_left, Root2->_left) &&  
        DoesTree1HaveTree2(Root1->_right,Root2->_right);  
}  
bool HasSubtree(BinaryTreeNode* Root1, BinaryTreeNode* Root2)  
{  
    bool result = false;  
  
    if(Root1 != NULL && Root2 != NULL)  
    {  
        if(Root1->_val == Root2->_val)  
            result = DoesTree1HaveTree2(Root1, Root2);  
        if(!result)  
            result = HasSubtree(Root1->_left, Root2);  
        if(!result)  
            result = HasSubtree(Root1->_right, Root2);  
    }  
  
    return result;  
}  
  

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);  
  
    ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);  
    ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);  
    ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);  
  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3);  
  
    Test("Test1", pNodeA1, pNodeB1, true);  
  
    DestroyTree(pNodeA1);  
    DestroyTree(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);  
  
    ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);  
    ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);  
    ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);  
  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3);  
  
    Test("Test2", pNodeA1, pNodeB1, false);  
  
    DestroyTree(pNodeA1);  
    DestroyTree(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);  
  
    ConnectTreeNodes(pNodeA1, pNodeA2, NULL);  
    ConnectTreeNodes(pNodeA2, pNodeA3, NULL);  
    ConnectTreeNodes(pNodeA3, pNodeA4, NULL);  
    ConnectTreeNodes(pNodeA4, pNodeA5, NULL);  
  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeB1, pNodeB2, NULL);  
    ConnectTreeNodes(pNodeB2, pNodeB3, NULL);  
  
    Test("Test3", pNodeA1, pNodeB1, true);  
  
    DestroyTree(pNodeA1);  
    DestroyTree(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);  
  
    ConnectTreeNodes(pNodeA1, pNodeA2, NULL);  
    ConnectTreeNodes(pNodeA2, pNodeA3, NULL);  
    ConnectTreeNodes(pNodeA3, pNodeA4, NULL);  
    ConnectTreeNodes(pNodeA4, pNodeA5, NULL);  
  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);  
  
    ConnectTreeNodes(pNodeB1, pNodeB2, NULL);  
    ConnectTreeNodes(pNodeB2, pNodeB3, NULL);  
  
    Test("Test4", pNodeA1, pNodeB1, false);  
  
    DestroyTree(pNodeA1);  
    DestroyTree(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);  
  
    ConnectTreeNodes(pNodeA1, NULL, pNodeA2);  
    ConnectTreeNodes(pNodeA2, NULL, pNodeA3);  
    ConnectTreeNodes(pNodeA3, NULL, pNodeA4);  
    ConnectTreeNodes(pNodeA4, NULL, pNodeA5);  
  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeB1, NULL, pNodeB2);  
    ConnectTreeNodes(pNodeB2, NULL, pNodeB3);  
  
    Test("Test5", pNodeA1, pNodeB1, true);  
  
    DestroyTree(pNodeA1);  
    DestroyTree(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);  
  
    ConnectTreeNodes(pNodeA1, NULL, pNodeA2);  
    ConnectTreeNodes(pNodeA2, NULL, pNodeA3);  
    ConnectTreeNodes(pNodeA3, NULL, pNodeA4);  
    ConnectTreeNodes(pNodeA4, NULL, pNodeA5);  
  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);  
    BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeB1, NULL, pNodeB2);  
    ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4);  
  
    Test("Test6", pNodeA1, pNodeB1, false);  
  
    DestroyTree(pNodeA1);  
    DestroyTree(pNodeB1);  
}  
  
// 树A为空树  
void Test7()  
{  
    BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);  
    BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeB1, NULL, pNodeB2);  
    ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4);  
  
    Test("Test7", NULL, pNodeB1, false);  
  
    DestroyTree(pNodeB1);  
}  
  
// 树B为空树  
void Test8()  
{  
    BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);  
    BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(9);  
    BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(3);  
    BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);  
  
    ConnectTreeNodes(pNodeA1, NULL, pNodeA2);  
    ConnectTreeNodes(pNodeA2, pNodeA3, pNodeA4);  
  
    Test("Test8", pNodeA1, NULL, false);  
  
    DestroyTree(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;  
}  


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值