树的子结构判断
来源:互联网 发布:淘宝1元拍卖可信吗 编辑:程序博客网 时间:2024/05/29 08:36
【题目】输入两棵二叉树A和B,判断B是不是A的子结构。
【分析】
典型的二叉树问题。
判断两个二叉树的所属关系,其实还是要从二叉树的结构特点出发,二叉树由根节点和左右孩子构成,如果一个二叉树是另一个的子树,说明这个二叉树根节点,左右孩子必然存在于另一个二叉树中,例如:
观察上图,发现第二个二叉树明显是第一个二叉树的子结构,首先,看根节点,8,第一棵树根节点为8,等于第二棵二叉树,观察其左右孩子结构,如果一致,说明所属关系成立,但是根结点为8的第一棵二叉树左孩子是8,第二棵二叉树左节点却是9,所以继续查看观察的第一棵二叉树的左子树,左子树第一个根节点就是8,所以看它的左右孩子,左孩子是9,等于第二棵二叉树,所以再看右孩子,是2,结构完全相等,说明第二棵二叉树是第一棵二叉树的子结构成立。
在判断过程中,很明显用递归方法比较简单,递归判断二叉树A的根结点和二叉树B根节点是否相同,找到相同的后,再递归判断左右孩子结构是否一致。
【示例代码】
#include<stdio.h>#include<stdlib.h>#define false 0#define true 1typedef struct BinaryTreeNode{ char data; struct BinaryTreeNode *left; struct BinaryTreeNode *right;}Node;//按照前序输入二叉树中结点的值//构建二叉树void create(Node **T){ char ch; scanf("%c",&ch); if(ch == '#') *T = NULL; else { *T = (Node *)malloc(sizeof(Node)); (*T)->data = ch; create(&(*T)->left); create(&(*T)->right); }}bool doestree1havetree2(Node *root1, Node *root2){ if(root2 == NULL) return true; if(root1 == NULL) return false; if(root1->data != root2->data) return false; return doestree1havetree2(root1->left,root2->left) &&doestree1havetree2(root1->right, root2->right);}bool hassubtree(Node *root1, Node *root2){ bool result = false; if(root1 != NULL && root2 != NULL) { if(root1 ->data == root2->data) result = doestree1havetree2(root1,root2); if(!result) result = hassubtree(root1->left, root2); if(!result) result = hassubtree(root1->right, root2); } return result;}void main(){ Node * root1 = NULL; Node * root2 = NULL; printf("二叉树1:\n"); create(&root1); printf("\n"); printf("二叉树2:\n"); getchar(); create(&root2); printf("\n"); printf("二叉树2是在二叉树1子构吗:\n"); bool r = hassubtree(root1, root2); if(r == false) printf("no, root2 is not root1's subtree!\n"); if(r == true) printf("yes, root2 is root1's subtree!\n"); printf("\n");}
【测试结果】
按照前序遍历创建二叉树1和2
在测试代码时,出现了问题,创建了二叉树1之后,二叉树2无法创建,究其原因是因为在创建链表过程中忽略了一个问题,在我们输入字符时都是先进入缓存区,scanf访问缓存得到数据,当我们把889##24##7##7##输完后输入回车,scanf读到回车符,就知道,输入完毕了,但是此时缓存区回车字符还在,当下一次输入89##2##时,先读取的是缓存区的回车符,然后才读89。。。这些数据,所以在建立树2时,清理缓存, getchar()清除缓冲区单一字符输入时scanf(“%c’,&a[i]);的换行符’\n’,除了getchar以外还有 fflush()是清除文件缓冲区,fflush(stdin); 如果没有这句,则stdio中还有数据,比如回车符,除此之外, scanf(“\n%d”,&c)也能达到效果,但不是清理缓存,而是自动将回车符读取了,scanf本来就是按照格式化的输入,所以当第一个输入为回车时它自动读取了,就不用清理缓存了。
- 树的子结构判断
- 判断树的子结构
- 判断树的子结构
- 剑指offer:判断树的子结构
- 判断二叉树的子结构
- 二叉树的子结构判断
- 剑指offer-树的子结构 判断二叉树B是不是A的子结构
- 判断树为另一树的子结构
- 重构二叉树&&判断二叉树的子结构
- 判断是否存在给定树的子结构
- 树------判断数A为数B的子结构
- 剑指offer-14 判断树的子结构
- 剑指offer-18:判断树的子结构
- 面试题18:判断树的子结构
- 判断B是否A的子结构
- 树的子结构(输入两个二叉树A与B,判断B是否是A的子结构)
- 树的子结构
- 树的子结构
- Map/Reduce执行流程
- 对比文件MD5差异并保存
- 初级程序员编码规范
- Spring整合JMS(一)——基于ActiveMQ实现
- ios开发-利用Xcode分析crashlog,并将其字符串化
- 树的子结构判断
- MeasureSpec详解 顺便解决了scrollView嵌套listView和GirdView的冲突
- VS 和Visual Assist X快捷键
- caller + 内部引用类和JNI本地函数 同一个ClassLoader
- 解决Mac下GDB提示签名错误
- Yii使用find findAll查找使用
- hibernate集合映射inverse和cascade详解
- DBCP连接池配置参数说明
- Android 软键盘控制弹出(很好使,自己写的,绝对能用)