T1是一棵含有几百万个节点的树,T2含有几百个节点。判断T2是否是T1 的子树。

首先考虑小数据量的情况,可以根据树的前序和中序遍历所得的字符串,来通过判断T2生成的字符串是否是T1字符串的子串,来判断T2是否是T1的子树。假设T1的节点数为N,T2的节点数为M。遍历两棵树算法时间复杂性是O(N + M), 判断字符串是否为另一个字符串的子串的复杂性也是O( N + M)(比如使用KMP算法)。所需要的空间也是O(N + M)。

这里有一个问题需要注意:对于左节点或者右节点为null的情况,需要在字符串中插入特殊字符表示。否则对于下面这种情形将会判断错误:

因此如果插入特殊字符,上述两棵树的中序和前序遍历的结果是相同的。

由于本例有几百万的节点,需要占用O(N + M)的内存。

如果换一种思路,就是遍历T1,每当T1的某个节点与T2的根节点值相同时,就判断两棵子树是否相同。这个算法的复杂度是O(N*M)。我们再仔细思考一下。因为只有在节点值与T2的根节点值相同才会调用O(M)。假设有K次这种情况,那么算法的复杂度就是O(N + K*M)。下面是代码实现:

struct TreeNode{TreeNode *leftChild;TreeNode *rightChild;int data;
};
// check sub tree n1 == sub tree n2bool checkSubTree(const TreeNode* n1, const TreeNode* n2){if( n1 == nullptr && n2 == nullptr )return true;if( n1 == nullptr || n2 == nullptr )return false;if( n1->data != n2->data )return false;return checkSubTree(n1->leftChild, n2->leftChild) && checkSubTree(n1->rightChild, n2->rightChild);
}
bool subTree(const TreeNode *n1, const TreeNode *n2){if( n1 == nullptr){return false; // the bigger tree is empty, so t2 is not subtree of t1}if( n1->data == n2->data){if( checkSubTree(n1, n2))return true;}return subTree(n1->leftChild, n2) || subTree(n2->rightChild, n2);
}

对于上面讨论的2种解法,哪种解法比较好呢?其实有必要好好讨论一番:

1)方法一会占用O(N + M)的内存,而另外一种解法只会占用O(logN + logM)的内存(递归的栈内存)。当考虑scalability扩展性时,内存使用的多寡是个很重要的因素。

2)方法一的时间复杂度为O(N + M),方法二最差的时间复杂度是O(N*M)。所以要通过工程实践或者是历史数据看一下哪种方法更优。当然了,方法二也可能会很早发现两棵树的不同,早早的退出了checkSubTree。

总的来说,在空间使用上,方法二更好。在时间上,需要通过实际数据来验证。

海量数据:判断一棵树是否为另一棵树的子树相关推荐

  1. 二叉树 判断一棵树是否是另一棵树的子树

    题目:判断判断一棵树是否是另一棵树的子树,子树的意思是只要包含了一个结点,就得包含这个结点下的所有节点.意思就是二叉树结点的值也要相等 如下图2就是1的子树 如果将第二颗树根节点右孩子data改为2 ...

  2. 判断一棵树是否为另一棵树的子树

    题目如下: 判断一棵树是否为另一棵树的子树 思路: (1)先构建两棵树,a树和b树,判断b树是否为a树的子树 (2)构建两个方法,一个用来判断传入的两棵树是否相同,为isSameTree:另一个用来判 ...

  3. 折半查找判定树——(快速判断某棵树是否为折半查找判定树)

    折半查找 也被称作二分查找,即将需要查找的元素与数组中间的元素进行比较:若比中间的元素小,则再与前子表的中间元素进行比较,以此类推直至查找到所需查找元素,或者所需查找元素不在此表中. 折半查找判定树( ...

  4. 判断一棵树是否是另一棵树的子树

    bool containsTree(TreeNode t1, TreeNode t2) { if (t2 == NULL)//空树一定是子树 { return true; } return subTr ...

  5. 一棵树是否为另一棵树的子结构

    题目描述 输入两颗二叉树A,B,判断B是不是A的子结构. 问题描述:给定两个二叉树的根节点,判断第二树是否是第一个树的子树,如果是返回1,否则返回0. 分析:这个是百度的一道笔试题目,属于经典的数据结 ...

  6. 一棵树是否为另一棵树的子树

    问题描述:给定两个二叉树的根节点,判断第二树是否是第一个树的子树,如果是返回1,否则返回0. 分析:这个是百度的一道笔试题目,属于经典的数据结构问题,子树判断问题,针对这个问题可以采用递归的方法判断, ...

  7. 树的应用:求树的叶子节点数 求树的高度、copy一棵树

    #if 0 //树的应用 //1.求树的叶子节点: 度为0的节点 //先判断根节点是否是叶子节点,然后计算左子树的叶子节点个数 //在计算 右子树节点个数void coutLeaf(BiNode *T ...

  8. LeetCode高频题:戈壁滩种树,一排n棵树,至少有k棵树存活时,最终形成的风景线有多少不同的情况

    LeetCode高频题:戈壁滩种树,一排n棵树,至少有k棵树存活时,最终形成的风景线有多少不同的情况 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是 ...

  9. Python 再说勾股树,这次整一棵五彩的任意“生长”的分形树!

    上一篇<Turtle库画一棵对称勾股树,美丽惊艳的分形世界!>中描绘了一棵对称的双色勾股树,详情见:Python Turtle库画一棵对称勾股树,美丽惊艳的分形世界!_汉阳Hann's H ...

最新文章

  1. python --那些你应该知道的知识点
  2. 在参数上使用@Param(“paramName”)注解”解决了传多个参数的问题
  3. c++能过,g++过不了
  4. Spring Cloud Feign 请求压缩 、Feign的日志级别配置
  5. java学习(141):自定义捕捉异常
  6. 腾讯云ubuntu18安装图形化界面
  7. 爬虫、请求库requests
  8. Linux安装SmartSVN及破解
  9. 第二代支付系统专题之报文篇(二)大额支付报文完整版(含二代新增功能业务说明)...
  10. 测绘地物的识别:建筑上怎么样区别挑廊、走廊、檐廊
  11. 数字孪生管理系统,智慧校园建设规划方案
  12. html光圈效果,PS新手教程:特效光圈效果
  13. 百度~网盘下载速度慢怎么办?完美解决,此账号被限速的完美解决,快100倍
  14. Word怎么在方框里打勾就是一个方框打上一个对号
  15. 学生信息管理系统(面向对象版本)V3.0
  16. 【redis】8数据结构(5种基本+3种特殊)
  17. Windows 10 (Win10) 将绿色免安装软件,添加到动态磁贴
  18. Win10切换共享文件夹账号
  19. PBOC/EMV之持卡人验证
  20. 小程序手持弹幕的原理及实现(uni-app)

热门文章

  1. emoji表情导致输入框maxlength失效
  2. B2C电商项目(第一天、项目搭建、Restful风格、拼音API、txMybatis、品牌增删改查、Swagger)
  3. 小学用计算机画图单元教学要求,小学电脑绘画教学探究
  4. 东方木在温州电脑市场买的联想笔记本win10如何关闭防火墙和杀毒软件
  5. JS和jQuery基础
  6. 设置web页面鼠标样式
  7. jenkins 配置安全策略admin没有Overall/Read权限
  8. 中科微北斗定位模组ATGM336H简介
  9. 不用软件测试火车速度,实测八款抢火车票软件 优先出票权仅拼速度非真正优先...
  10. 输出保留3位小数(YZOJ-1008)