剑指offer_面试题18_树的子结构

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

两个步骤:

1、第一步在树 A 中找到和树 B 的根结点的值一样的结点 R

2、第二步再判断树 A 中以 R 为根结点的子树是不是包含和树 B 一样的结构。

对于递归:想好判断条件,以及 什么条件下该去递归。

#include <iostream>
#include <cstdlib>

using namespace std;

typedef struct node{
    int m_pValue;
    struct node *lchild;
    struct node *rchild;
}TreeNode;

/**创建一个二叉树结点*/
TreeNode * create_Treenode(int elem)
{
    TreeNode *pRoot;
    pRoot = new TreeNode;
    pRoot->m_pValue = elem;
    pRoot->lchild = NULL;
    pRoot->rchild = NULL;

    return pRoot;
}

/**将二叉树结点连接起来,组成一颗二叉树*/
TreeNode * connect_Treenode(TreeNode *pRoot, TreeNode *p_lchild, TreeNode *p_rchild)
{
    if(NULL == pRoot)
        return pRoot;

    pRoot->lchild = p_lchild;
    pRoot->rchild = p_rchild;

    return pRoot;
}

//TreeNode * delete_node()

/**在根结点找到的情况下,判断树1中是否存在树2的结构*/
bool Does_tree1_have_tree2(TreeNode *pRoot1,TreeNode *pRoot2)
{
    if(pRoot2 == NULL)   /**在找的过程中,如果树2遍历到了叶节点,说明前面的节点都相同*/
        return true;
    if(pRoot1 == NULL)   /**树1遍历到叶结点,说明找不到树2中的结点*/
        return false;

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

    return Does_tree1_have_tree2(pRoot1->lchild,pRoot2->lchild) &&
        Does_tree1_have_tree2(pRoot1->rchild,pRoot2->rchild);
}

/**感觉写递归,就是想好一步应该判断的条件,什么情况下返回*/

/**找根结点*/
bool Hassubtree(TreeNode *pRoot1,TreeNode *pRoot2)
{
    bool result = false;

    if(pRoot1 != NULL && pRoot2 != NULL)
    {
        if(pRoot1->m_pValue == pRoot2->m_pValue)
            result = Does_tree1_have_tree2(pRoot1,pRoot2);
        if(!result)                    /**如果根结点不是,那先去找左孩子*/
            result = Hassubtree(pRoot1->lchild,pRoot2);
        if(!result)                    /**如果左孩子还不是,那去找右孩子*/
            result = Hassubtree(pRoot1->rchild,pRoot2);
    }

    return result;
}

/**测试函数,来源于书本,学习了这种测试函数写法,很有收获*/
void Test(const char* testName, TreeNode* pRoot1, TreeNode* pRoot2, bool expected)   /**此处 testName 前应该加 const*/
{
    if(Hassubtree(pRoot1, pRoot2) == expected)
        cout << testName << " passed." << endl;
    else
        cout << testName << " failed." << endl;
}

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

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

    TreeNode* pNodeB1 = create_Treenode(8);
    TreeNode* pNodeB2 = create_Treenode(9);
    TreeNode* pNodeB3 = create_Treenode(2);

    connect_Treenode(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()
{
    TreeNode* pNodeA1 = create_Treenode(8);
    TreeNode* pNodeA2 = create_Treenode(8);
    TreeNode* pNodeA3 = create_Treenode(7);
    TreeNode* pNodeA4 = create_Treenode(9);
    TreeNode* pNodeA5 = create_Treenode(3);
    TreeNode* pNodeA6 = create_Treenode(4);
    TreeNode* pNodeA7 = create_Treenode(7);

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

    TreeNode* pNodeB1 = create_Treenode(8);
    TreeNode* pNodeB2 = create_Treenode(9);
    TreeNode* pNodeB3 = create_Treenode(2);

    connect_Treenode(pNodeB1, pNodeB2, pNodeB3);

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

    //DestroyTree(pNodeA1);
    //DestroyTree(pNodeB1);
}

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

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

    TreeNode* pNodeB1 = create_Treenode(8);
    TreeNode* pNodeB2 = create_Treenode(9);
    TreeNode* pNodeB3 = create_Treenode(2);

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

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

    //DestroyTree(pNodeA1);
    //DestroyTree(pNodeB1);
}

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

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

    TreeNode* pNodeB1 = create_Treenode(8);
    TreeNode* pNodeB2 = create_Treenode(9);
    TreeNode* pNodeB3 = create_Treenode(3);

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

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

    //DestroyTree(pNodeA1);
    //DestroyTree(pNodeB1);
}

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

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

    TreeNode* pNodeB1 = create_Treenode(8);
    TreeNode* pNodeB2 = create_Treenode(9);
    TreeNode* pNodeB3 = create_Treenode(2);

    connect_Treenode(pNodeB1, NULL, pNodeB2);
    connect_Treenode(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()
{
    TreeNode* pNodeA1 = create_Treenode(8);
    TreeNode* pNodeA2 = create_Treenode(8);
    TreeNode* pNodeA3 = create_Treenode(9);
    TreeNode* pNodeA4 = create_Treenode(2);
    TreeNode* pNodeA5 = create_Treenode(5);

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

    TreeNode* pNodeB1 = create_Treenode(8);
    TreeNode* pNodeB2 = create_Treenode(9);
    TreeNode* pNodeB3 = create_Treenode(3);
    TreeNode* pNodeB4 = create_Treenode(2);

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

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

    //DestroyTree(pNodeA1);
    //DestroyTree(pNodeB1);
}

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

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

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

    //DestroyTree(pNodeB1);
}

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

    connect_Treenode(pNodeA1, NULL, pNodeA2);
    connect_Treenode(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();
    return 0;
}

/*点滴积累,我的一小步O(∩_∩)O~*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值