IT面试题---如何确定一棵二叉树是另一棵二叉树的子树(2)
来源:互联网 发布:扫一扫软件免费下载 编辑:程序博客网 时间:2024/05/18 06:39
不了解题目背景的同学请先阅读:IT面试题---如何确定一棵二叉树是另一棵二叉树的子树(1)
举例:下图中S显然是T的子树
Tree S x / \ a b \ c Tree T z / \ x e / \ \ a b k \ c
在之前的blog中我们讨论过了一种O(NM)的解法,这里我们讨论一种更为优化的解法,
我们注意到对于二叉树来说中序遍历和前序遍历可以唯一地识别一棵二叉树
因此算法描述如下:
1. 存储树T的中序遍历和前序遍历于数组inT, preT
2. 存储树S的中序遍历和前序遍历于数组inS, preS
3. 如果inS是inT的子序列且preS是preT的子序列,那么S就是T的子树
T的中序和前序遍历序列如下:inT[] = {a, c, x, b, z, e, k}preT[] = {z, x, a, c, b, e, k}S的中序和前序遍历序列如下:inS[] = {a, c, x, b}preS[] = {x, a, c, b}显然inS是inT的子序列,preS是preT的子序列
但是上述算法仍然拥有缺陷,考虑以下两棵树,光从序列考察,S是T的子树,但很显然事实上它不是
Tree S x / \ a b / c PreS = xacb InS = caxb
Tree T x / \ a b / \ c d
PreT = xacbd InT = caxbd
原因在于以上序列没有将空指针考虑在内,因此如果我们做一个变化,将空孩子用$表示,则上述序列则变化为:
Tree S x / \ a b / c PreS = xac$$$b$$ InS = $c$a$x$b$
Tree T x / \ a b / \ c d
PreT = xac$$$b$d$$ InT = $c$a$x$b$d$
那么PreS自然就不是PreT的子序列了,这样我们的结论就成立了。
你还不放心?OK,让我们用这种方法再看看之前的例子
Tree S x / \ a b \ cPreS = xa$c$$b$$ inS = $a$c$x$b$ Tree T z / \ x e / \ \ a b k \ c
PreT = zxa$c$$b$$e$k$$ inT = $a$c$x$b$z$e$k$
显然,结论成立。
实现代码如下:
#include <iostream>#include <cstring>using namespace std;#define MAX 100 // 二叉树节点struct Node{ char key; struct Node *left, *right;}; // 新建子节点Node *newNode(char item){ Node *temp = new Node; temp->key = item; temp->left = temp->right = NULL; return temp;} // 构造中序序列void storeInorder(Node *root, char arr[], int &i){ if (root == NULL) { arr[i++] = '$'; return; } storeInorder(root->left, arr, i); arr[i++] = root->key; storeInorder(root->right, arr, i);} // 构造前序序列void storePreOrder(Node *root, char arr[], int &i){ if (root == NULL) { arr[i++] = '$'; return; } arr[i++] = root->key; storePreOrder(root->left, arr, i); storePreOrder(root->right, arr, i);} /* S是不是T的子树 */bool isSubtree(Node *T, Node *S){ if (S == NULL) return true; if (T == NULL) return false; // 打造S和T的中序序列 int m = 0, n = 0; char inT[MAX], inS[MAX]; storeInorder(T, inT, m); storeInorder(S, inS, n); inT[m] = '\0', inS[n] = '\0'; // inS是不是inT的子序列 if (strstr(inT, inS) == NULL) return false; // 打造S和T的前序序列 m = 0, n = 0; char preT[MAX], preS[MAX]; storePreOrder(T, preT, m); storePreOrder(S, preS, n); preT[m] = '\0', preS[n] = '\0'; // preS是不是preT的子序列 return (strstr(preT, preS) != NULL);} // 测试用例int main(){ Node *T = newNode('a'); T->left = newNode('b'); T->right = newNode('d'); T->left->left = newNode('c'); T->right->right = newNode('e'); Node *S = newNode('a'); S->left = newNode('b'); S->left->left = newNode('c'); S->right = newNode('d'); if (isSubtree(T, S)) cout << "Yes: S is a subtree of T"; else cout << "No: S is NOT a subtree of T"; return 0;}
显然该算法达到了线性时间复杂度
关于strstr的实现,可以参照
http://blog.csdn.net/v_july_v/article/details/7041827
0 0
- IT面试题---如何确定一棵二叉树是另一棵二叉树的子树(2)
- IT面试题---如何确定一棵二叉树是另一棵二叉树的子树(1)
- 判断一棵二叉树是否是另一棵二叉树的子树
- 如何判断一棵二叉树树是否为另一棵二叉树的子树
- 二叉树面试题之判断一棵树是否为另一棵树的子树
- 判断一棵二叉树是否是另一棵树的子树
- 判断一个节点是否在一棵二叉树中和判断一颗二叉树是否是另一颗树的子树——题集(十二)
- 一棵二叉树是否为另一棵二叉树的子树
- 判断一棵二叉树是不是另一棵二叉树的子树
- 判断一棵二叉树是否为另一棵二叉树的子树,Python实现
- 确定一个二叉树是另一个二叉树的子树
- 【IT笔试面试题整理】判定一棵二叉树是否是二叉搜索树-转
- day14之判断一个节点是否在一棵二叉树中+判断一颗二叉树是是否是另一颗树的子树
- 【判断一个节点是否在一棵二叉树中】/【判断一颗二叉树是是否是另一颗树的子树】
- 判断一个节点是否在一棵二叉树中&判断一颗二叉树是是否是另一颗树的子树
- 判断一个节点是否在一棵二叉树中&&判断一颗二叉树是是否是另一颗树的子树
- 判断一颗二叉树是是否是另一颗树的子树。比如tree2是tree1的子树
- 判断一颗二叉树是是否是另一颗树的子树
- hdu 3264 Open-air shopping malls 2009 Asia Ningbo Regional Contest Hosted by NIT
- JeeSite
- 程序员怎样学习英语
- 在MyEclipse中配置tomcat
- 集合和反编译间的深入理解和认识
- IT面试题---如何确定一棵二叉树是另一棵二叉树的子树(2)
- H264 TS/ES
- linux操作命令
- LeetCode: LRU Cache
- Girl_iOS100天学iOS的第十天(单例和通知)
- 批处理学习教程
- 程序员牛人跳槽
- 为什么很多程序员都选择跳槽?
- 跳槽