剑指offer--018(树的子结构)

题目描述

输入两棵树A和B,判断B是不是A的子结构。

思路:
  • 如果A和B两个树中任意一个树为空树,则一定没有子结构

  • 采用递归思想,将二叉树划分为根节点,左子树和右子树

  • 如果根节点相同,比较左右子树是否相等

  • 如果根节点不相同,去左子树中进行比较

  • 如果在左子树中没有找到,去右子树中进行比较


代码:

typedef  struct BTreeNode
{
    int _data;
    struct BTreeNode* _left;
    struct BTreeNode* _right;
}BTreeNode;


BTreeNode* CreateBTree(int* a, int* pIndex, int x);
BTreeNode* BuyNode(int x);


bool HasSubtree(BTreeNode* pRoot1, BTreeNode* pRoot2);
bool IfChildTree(BTreeNode* root1, BTreeNode* root2);
void PrevOrder(BTreeNode* root);


BTreeNode* BuyNode(int x)
{
    BTreeNode* node = (BTreeNode*)malloc(sizeof(BTreeNode));
    if (node != NULL)
    {
        node->_data = x;
        node->_left = NULL;
        node->_right = NULL;
    }
    return node;
}
BTreeNode* CreateBTree(int* a, int* pIndex, int x)
{
    assert(a);

    BTreeNode* tree = NULL;

    if (a[*pIndex] == x)
        return NULL;

    tree = BuyNode(a[*pIndex]);

    (*pIndex)++;
    tree->_left = CreateBTree(a, pIndex, x);
    (*pIndex)++; 
    tree->_right = CreateBTree(a, pIndex, x);

    return tree;
}


void PrevOrder(BTreeNode* root)
{
    if (root == NULL)
        return;

    printf("%d ", root->_data);
    PrevOrder(root->_left);
    PrevOrder(root->_right);
}



bool HasSubtree(BTreeNode* pRoot1, BTreeNode* pRoot2)
{
    bool result = false;
    //有一个为空,即不是子树
    if (pRoot1 == NULL || pRoot2 == NULL)
    {
        return result;

    }
    else
    {
        if (pRoot1->_data == pRoot2->_data)
        {
            result = IfChildTree(pRoot1, pRoot2);//如果两个根节点的值相等,就去比较左子树相不相等
        }

        if (!result)
        {
            result = HasSubtree(pRoot1->_left, pRoot2);//如果不相等,就以左子树为根节点找子树

        }

        if (!result)
        {
            result = HasSubtree(pRoot1->_right, pRoot2);//如果不相等,就以右子树为根节点找子树
        }
    }

    return result;
}

bool IfChildTree(BTreeNode* root1, BTreeNode* root2)
{
    if (root2 == NULL)
    {
        //如果树2为空,表示是子树
        return true;
    }

    //如果树1为空,表示不是子树
    if (root1 == NULL)
        return false;


    //如果数值不相等,不是子树
    if (root1->_data != root2->_data)
        return false;



    //如果根节点数值相等,以左子树和右子树为根节点,比较是否相等
    return  IfChildTree(root1->_left, root2->_left) && IfChildTree(root1->_right, root2->_right);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值