数的子结构

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

二叉树结点的定义如下:

struct BinaryTreeNode
{
    int             m_nValue;
    BinaryTreeNode *m_pLeft;
    BinaryTreeNode *m_pRight;
};

分析:采用递归,先找到值相同的结点,再判断是否相同。

  1 #include<stdio.h>
  2
  3 struct BinaryTreeNode
  4 {
  5     int              m_nValue;
  6     BinaryTreeNode*  m_pLeft;
  7     BinaryTreeNode*  m_pRight;
  8 };
  9
 10 BinaryTreeNode* CreateBinaryTreeNode(int value)
 11 {
 12     BinaryTreeNode* pNode = new BinaryTreeNode();
 13     pNode->m_nValue = value;
 14     pNode->m_pLeft = NULL;
 15     pNode->m_pRight = NULL;
 16 }
 17
 18 void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft,
 19                     BinaryTreeNode* pRight)
 20 {
 21     if(pParent != NULL)
 22     {
 23         pParent->m_pLeft = pLeft;
 24         pParent->m_pRight = pRight;
 25     }
 26 }
 27
 28 void DestroyTree(BinaryTreeNode* pRoot)
 29 {
 30     if(pRoot != NULL)
 31     {
 32         BinaryTreeNode* pLeft = pRoot->m_pLeft;
 33         BinaryTreeNode* pRight = pRoot->m_pRight;
 34
 35         delete pRoot;
 36         pRoot = NULL;
 37
 38         DestroyTree(pLeft);
 39         DestroyTree(pRight);
 40     }
 41 }
 42
 43 bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
 44
 45 bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
 46 {
 47     bool result = false;
 48
 49     if(pRoot1 != NULL && pRoot2 != NULL)
 50     {
 51         if(pRoot1->m_nValue == pRoot2->m_nValue)
 52             result = DoesTree1HaveTree2(pRoot1, pRoot2);
 53         if(!result)
 54             result = HasSubtree(pRoot1->m_pLeft, pRoot2);
 55         if(!result)
 56             result = HasSubtree(pRoot1->m_pRight, pRoot2);
 57     }
 58
 59     return result;
 60 }
 61
 62 bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
 63 {
 64     //如果pRoot2 == NULL 说明树B已经到达叶子结点了
 65     //无论pRoot1是否到达一个叶子结点,都应该返回真
 66     if(pRoot2 == NULL)
 67         return true;
 68
 69     //如果程序执行到这里,则pRoot2一定不是NULL,
 70     //如果pRoot1 == NULL, 则说明树A不包含树B
 71     if(pRoot1 == NULL)
 72         return false;
 73
 74     if(pRoot1->m_nValue != pRoot2->m_nValue)
 75         return false;
 76
 77     return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
 78         DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
 79
 80 }
 81
 82 //         树A              树B
 83 //          8               8
 84 //       /   \            /   85 //     8      7          9    2
 86 //    /  \
 87 //   9    2
 88 //      /   89 //     4    7
 90 //树B是树A的子树
 91
 92 int main()
 93 {
 94     BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
 95     BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
 96     BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7);
 97     BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9);
 98     BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(2);
 99     BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4);
100     BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7);
101
102     ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
103     ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
104     ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);
105
106     BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
107     BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
108     BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);
109
110     ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3);
111
112     if(HasSubtree(pNodeA1, pNodeB1))
113         printf("tree B is Subtree of tree A\n");
114     else
115         printf("tree B is‘t Subtree of tree A\n");
116
117     DestroyTree(pNodeA1);
118     DestroyTree(pNodeB1);
119 }

时间: 2024-12-08 09:14:50

数的子结构的相关文章

算法:数的子结构

题目: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 思路: 1.首先设置标志位result = false,因为一旦匹配成功result就设为true,剩下的代码不会执行,如果匹配不成功,默认返回false2.递归思想,如果根节点相同则递归调用baoHan(),如果根节点不相同,则判断tree1的左子树和tree2是否相同,再判断右子树和tree2是否相同3.注意null的条件,HasSubTree中,如果两棵树都不为空才进行判断,baoHan中,

判断一颗二叉树是不是另外一颗的子结构

这是一道比较经典的题目.我先是在百度的在线笔试中遇到,然后发现剑指Offer上有原题.当然题目并不完全一样不过大致相同. 百度笔试是给你两个根节点判断第棵树是不是第一棵树的子树.剑指Offer是问你第二颗数是不是第一棵树的子结构(也就是说可是是第一棵二叉树的中间阶段). 笔试的时候恁是没完全通过测试案例,就差几个,实在也是不知道是什么问题.这次剑指Offer的在线测试中,发现他的描述不是很准确.我一开始以为空树是任何树的子结构,结果空树不是任何数的子结构. 第一版代码:算法复杂度是O(M * N

算法课作业之删数问题

问题描述: 通过键盘输入一个高精度的正整数n(n的有效位数≤240),去掉其中任意s个数字后,剩下的数字按原左右次序将组成一个新的正整数.编程对给定的n和s,寻找一种方案,使得剩下的数字组成的新数最小. 问题分析: 这个问题是最优子结构问题,即局部最优能决定全局最优解,可以使用贪心算法进行解决.n个正整数去掉s个数字,求使得到的新的正整数最大的删除方案可以等价为:对于n个正整数组成的数字,一个一个地依次去掉s个数字,要求每删除一个数时,都使删除后的新的正整数最小.因此问题转化为求解删除一个数字时

NOIP2007 矩阵取数游戏

题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. 每次取走的各个元素只能是该元素所在行的行首或行尾: 3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素值*2i, 其中i 表示第i 次取数(从1 开始编号): 4. 游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个

剑指offer——树的子结构 (JAVA代码)

版权声明:本文为博主原创文章,未经博主允许不得转载. 题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构). 解题思路: 首先看牛客网给出的测试用例: 一般对于树的操作不像链表一样,操作更复杂,如果使用循环遍历的话,对于非完全二叉树规律难寻,一般通用的方法就是使用递归求解,本题也不例外,同样使用递归求解,求解的大体思路是首先判断B的根节点和A的根节点是否相同(这里的相同是指节点的值相同并且左右子节点相同),如果相同比较他们的左右子节点,这一步骤是

动态规划和子结构的浅谈

1 def fib(n): 2 global numCails 3 numCails +=1 4 print "numCails-->",numCails 5 print "n---->",n 6 if n <=1: 7 return n 8 else: 9 return fib(n-1) + fib(n-2) 我们先看看之前的代码.这是一个 斐波那契数列 我们知道这个代码的执行会有很多重叠的子结构. 让我们先看下图{我今天不用笔画了 LOL} {

hdu 2085 数塔 -- dp模板题

数塔 Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少? 已经告诉你了,这是个DP的题目,你能AC吗? Input 输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内. Outp

树的子结构(剑指offer)递归

树的子结构 参与人数:1611时间限制:1秒空间限制:32768K 通过比例:18.19% 最佳记录:0 ms|0K(来自  mearo) 题目描述 输入两颗二叉树A,B,判断B是不是A的子结构. 链接:http://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 思路:判断A

【日常学习】【区间DP+高精】codevs1166 矩阵取数游戏题解

题目来自NOIP2007TG3 如果在考场上我现在已经歇菜了吧 今天一整天的时间全部投在这道题上,收获不小. 先上题目 题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. 每次取走的各个元素只能是该元素所在行的行首或行尾: 3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素