kmp应用2

  1. 题目:
    题目描述:判断一棵树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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值