给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
求解思路
两个序列是否对应相同搜索树的判别
1、分别建两棵搜索树的判别方法
项目根据两个序列分别建树,再判别树是否一样* 根据两个序列分别建树,再判别树是否一样
2、不建树的判别方法
3、建立一棵树,再判别其他序列是否与该树一致
第一种方法:先建立一个二叉树,在此树中查找后面序列的节点,若每次查找所经过的节点在之前都出现过则一致,若某次查找经过的节点没有出现过则不一致。
#include <iostream>
using namespace std;
typedef struct TreeNode *Tree;
struct TreeNode
{
TreeNode(){}
~TreeNode(){}
int content;
Tree left, right;
int flag;
};
Tree MakeTree(int N);
Tree NewNode(int contents);
Tree Insert(Tree T, int contents);
int Judge(Tree T, int N);
void ResetT(Tree T);
int check(Tree T, int V);
void FreeTree(Tree T);
Tree MakeTree(int N)//建树
{
Tree T=nullptr;
int i, contents;
cin >> contents;
T = NewNode(contents);
for (i = 1; i < N;++i)//插入树节点
{
cin >> contents;
T = Insert(T, contents);
}
return T;
}
Tree NewNode(int contents)
{
Tree T = (Tree)malloc(sizeof(struct TreeNode));
T->content = contents;
T->left = T->right = nullptr;
T->flag = 0;
return T;
}
Tree Insert(Tree T, int contents)//插入树节点
{
if (!T)
T = NewNode(contents);//若是空树,创建新的节点
else{
if (contents<T->content) //若要插入的节点值小于当前节点值,插入左子树
T->left = Insert(T->left,contents);
else T->right = Insert(T->right,contents);
}
return T;
}
int Judge(Tree T, int N)//判断是否为同一二叉树
{
int i, V, flag = 0;//flag为0说明还是一致的
cin >> V;
if (V != T->content)flag = 1;//根节点不相同说明不是同一颗
else T->flag = 1; //相同则把当前节点的flag变成1,表示已经路过了
for (i = 1; i < N;++i)
{
cin >> V;//输入剩余的节点值
if ((!flag)&&(!check(T, V)))flag =1;//若flag=0(这一步之前还是一致的),那么进行这次check,if=0(这次不一致)
}
if (flag)return 0;
else return 1;
}
void ResetT(Tree T)
{
if (T->left)ResetT(T->left);
if (T->right)ResetT(T->right);
T->flag = 0;
}
int check(Tree T, int V)
{
if (T->flag)//如T已被路过
{
if (V < T->content)return check(T->left, V);
else if (V>T->content)return check(T->right, V);
else return 0;
}
else//没被路过
{
if (V==T->content)//该节点就是我们要找的
{
T->flag = 1;
return 1;
}
else return 0;
}
}
void FreeTree(Tree T)
{
if (T->left)FreeTree(T->left);
if (T->right)FreeTree(T->right);
free(T);
}
int main()
{
int N, L, i;
Tree T;
cin >> N;
while (N)
{
cin >> L;
T = MakeTree(N);
for (i = 0; i < L; ++i)
{
if (Judge(T, N))cout << "Yes"<<endl;
else cout << "No"<<endl;
// ResetT(T);
}
// FreeTree(T);
cin >> N;
}
system("pause");
return 0;
}
第二种方法:每个序列建立一棵树,比较他们的先序遍历序列,一致则是,否则不是
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
using namespace std;
int N, L, pos, samejudgement[100];
typedef struct node
{
node(int a, node* b, node* c)
{
data = a;
l = b;
r = c;
}
int data;
struct node *l;
struct node *r;
}*BST;
void PreOrderTraverse(BST T)
{
if (T)
{
samejudgement[pos++] = T->data;
PreOrderTraverse(T->l);
PreOrderTraverse(T->r);
}
}
bool PreOrderTraverse_test(BST T)
{
if (T)
{
// cout<<"gg1111 "<<samejudgement[pos]<<" "<<pos<<endl;
if (samejudgement[pos++] != T->data) return false;
// cout<<"gg2222 "<<pos<<endl;
if (!PreOrderTraverse_test(T->l)) return false;
if (!PreOrderTraverse_test(T->r)) return false;
}
return true;
}
void Inset_BST(BST &T, int data)
{
if (T == NULL)
{
T = new node(data, NULL, NULL);
}
else if (T->data > data)
{
Inset_BST(T->l, data);
}
else Inset_BST(T->r, data);
}
int main()
{
while (scanf("%d", &N) != EOF)
{
if (N) scanf("%d", &L);
else break;
pos = 0;
memset(samejudgement, 0, sizeof(samejudgement));
BST tree = NULL;
for (int i = 0; i < N; i++)
{
int t; scanf("%d", &t);
Inset_BST(tree, t);
}
PreOrderTraverse(tree);
//for(int i=0;i<pos;i++) cout<<"输出中间值 "<<samejudgement[i]<<endl;
bool flag = true;
for (int i = 0; i < L; i++)
{
flag = true;
BST test_tree = NULL;
pos = 0;
for (int j = 0; j < N; j++)
{
int t; scanf("%d", &t);
Inset_BST(test_tree, t);
}
//PreOrderTraverse_test(test_tree);
if (!PreOrderTraverse_test(test_tree)) flag = false;
if (flag) printf("Yes\n");
else printf("No\n");
}
//if(flag) printf("Yes\n");
//else printf("No\n");
}
return 0;
}
第三种不建树的方法: