- 题目:
题目描述:判断一棵树T2是否是另一棵树T1的子树结构。如下图T2就是T1的一棵子树
*例子: T1 T2
* 1 3
* / \ / \
* 2 3 6 7
* / \ / \
* 4 5 6 7
/*解法1:暴力的尝试每一个节点,遍历母树T1,当遇到开头字符和子树T2一致的时候,按照子树的结构去遍历母树T1
*/
*解法2:kmp解法,二叉树的序列化
(注意要保证唯一性,即一个结点结束后,需要添加一个特殊符号来标记结束,
之后遇到NULL再使用一个不同的特殊符号来标记),将树变为字符串,之后kmp判断即可
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std;
typedef struct Node
{
int val;
struct Node* left;
struct Node* right;
}treeNode;
void Create_T1(treeNode** tree)
{
*tree = (treeNode*)malloc(sizeof(treeNode));
(*tree)->val = 1;
//左子树
(*tree)->left = (treeNode*)malloc(sizeof(treeNode));
(*tree)->left->val = 2;
//左的左
(*tree)->left->left = (treeNode*)malloc(sizeof(treeNode));
(*tree)->left->left->val = 4;
(*tree)->left->left->left = NULL;
(*tree)->left->left->right = NULL;
//左的右
(*tree)->left->right = (treeNode*)malloc(sizeof(treeNode));
(*tree)->left->right->val = 5;
(*tree)->left->right->left = NULL;
(*tree)->left->right->right = NULL;
//右子树
(*tree)->right = (treeNode*)malloc(sizeof(treeNode));
(*tree)->right->val = 3;
//右的左
(*tree)->right->left = (treeNode*)malloc(sizeof(treeNode));
(*tree)->right->left->val = 6;
(*tree)->right->left->left = NULL;
(*tree)->right->left->right = NULL;
//右的右
(*tree)->right->right = (treeNode*)malloc(sizeof(treeNode));
(*tree)->right->right->val = 7;
(*tree)->right->right->left = NULL;
(*tree)->right->right->right = NULL;
}
void Create_T2(treeNode** tree)
{
(*tree) = (treeNode*)malloc(sizeof(treeNode));
(*tree)->val = 3;
(*tree)->left = (treeNode*)malloc(sizeof(treeNode));
(*tree)->left->val = 6;
(*tree)->left->left = NULL;
(*tree)->left->right = NULL;
(*tree)->right = (treeNode*)malloc(sizeof(treeNode));
(*tree)->right->val = 7;
(*tree)->right->left = NULL;
(*tree)->right->right = NULL;
}
//test for preOrder
void preOrder(treeNode* tree)
{
if(tree)
{
printf("%d ",tree->val);
preOrder(tree->left);
preOrder(tree->right);
}
}
vector<int> GetNextArr(string str2)
{
int len = str2.length();
std::vector<int> next(len);
next[0] = -1;
next[1] = 0;
int pos = 2;
int cn = 0;
while(pos < next.size()){
if(str2[pos-1] == str2[cn]){
next[pos++] = ++cn;
}else if(cn > 0){
cn = next[cn];
}else{
next[pos++] = 0;
}
}
return next;
}
int GetIndex(string str1, string str2)
{
int len1 = str1.length();
int len2 = str2.length();
if(len1 == 0 || len2 == 0 || len1 < len2 || str1.empty() || str2.empty())
return -1;
int i = 0;
int j = 0;
std::vector<int> next = GetNextArr(str2);
while(i < len1 && j < len2)
{
if (str1[i] == str2[j]){
i++,j++;
}else if(next[j] == -1){
i++;
}else{
j = next[j];
}
}
return j == len2 ? i-j : -1;
}
//preOrder
string Tree_To_string(treeNode* tree)
{
if(tree == NULL)
return "#_";
string str = to_string(tree->val) + "_";
return str + Tree_To_string(tree->left)+Tree_To_string(tree->right);
}
bool T1SubtreeEqualsT2(treeNode* T1, treeNode* T2)
{
string str1 = Tree_To_string(T1);
string str2 = Tree_To_string(T2);
return GetIndex(str1,str2) != -1;
}
int main()
{
treeNode* T1 = NULL;
treeNode* T2 = NULL;
Create_T1(&T1);
Create_T2(&T2);
printf("T1's preOrder:");
preOrder(T1);
puts(" ");
printf("-------------------\n");
printf("T2's preOrder:");
preOrder(T2);
puts(" ");
if(T1SubtreeEqualsT2(T1,T2))
cout<<"T1SubtreeEqualsT2 is true"<<endl;
cout<<"T1SubtreeEqualsT2 is false"<<endl;
return 0;
}