给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
输入样例:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
输出样例:
Yes
No
No
我们知道,**如果知道了一棵树的先序遍历和中序遍历,便可以唯一确定一棵树,**而对于本题中二叉搜索树,中序遍历都是一样的,所以我们只需要对比各树的先序遍历是否一样,便可以判断是否是同一颗二叉搜索树。
代码如下
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
typedef int ElementType;
typedef struct TNode* Position;
typedef Position BinTree;
struct TNode {
ElementType Data;
BinTree Left;
BinTree Right;
};
BinTree Insert(BinTree BST, ElementType X);
BinTree Delete(BinTree BST, ElementType X);
Position FindMin(BinTree BST);
void PreOrderTraversal(BinTree T, int* a);
void InOrderTraversal(BinTree T, int* a);
typedef struct SNode* Stack;
struct SNode
{
Position data[MAXSIZE];
int top;
};
Stack CreateStack();
int IsEmpty(Stack S);
int Push(Stack S, Position data);
Position Pop(Stack S);
//树和栈都由我们自己定义
int main()
{
BinTree BST;
BinTree BSTcheck[100];
ElementType X;
int N, i, L, j;
BST = NULL;
for (i = 0; i < 100; ++i)
{
BSTcheck[i] = NULL;
}
int binordert[MAXSIZE];
int bcheckinordert[100][MAXSIZE];
while (1)
{
scanf("%d", &N);
if (N == 0)
break;
else
{
scanf("%d", &L);
for (i = 0; i < N; i++)
{
scanf("%d", &X);
BST = Insert(BST, X);
}
PreOrderTraversal(BST, binordert); //将先序遍历存入数组binordert
for (j = 0; j < L; ++j)
{
for (i = 0; i < N; i++)
{
scanf("%d", &X);
BSTcheck[j] = Insert(BSTcheck[j], X);
}
PreOrderTraversal(BSTcheck[j], bcheckinordert[j]);
}
for (j = 0; j < L; ++j)
{
for (i = 0; i < N; ++i)
{
if (binordert[i] != bcheckinordert[j][i])
{
printf("No\n");
break;
}
else if(i == N-1)
{
printf("Yes\n");
}
}
}
for (i = 1; i <= N; ++i)
{
BST = Delete(BST, i);
}
for (j = 0; j < L; ++j)
{
for (i = 1; i <= N; ++i)
{
BSTcheck[j] = Delete(BSTcheck[j], i);
}
}
}
}
return 0;
}
Stack CreateStack()
{
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->top = -1;
return S;
}
int IsEmpty(Stack S)
{
if (S->top == -1)
return 1;
else
return 0;
}
int Push(Stack S, Position data)
{
if (S->top == MAXSIZE - 1)
{
printf("栈满");
return 0;
}
else
{
++S->top;
S->data[S->top] = data;
return 1;
}
}
Position Pop(Stack S)
{
Position data;
if (IsEmpty(S))
{
printf("栈空");
return NULL;
}
else
{
data = S->data[S->top];
--S->top;
return data;
}
}
Position FindMin(BinTree BST)
{
Position P;
P = BST;
if (P == NULL)
return NULL;
else
while (P->Left != NULL)
{
P = P->Left;
}
return P;
}
BinTree Insert(BinTree BST, ElementType X)
{
if (BST == NULL)
{
BST = (BinTree)malloc(sizeof(struct TNode));
BST->Data = X;
BST->Left = NULL;
BST->Right = NULL;
}
else
{
Position P;
P = BST;
while (1)
{
if (X > P->Data)
{
if (P->Right != NULL)
P = P->Right;
else
{
P->Right = (BinTree)malloc(sizeof(struct TNode));
P->Right->Data = X;
P->Right->Left = NULL;
P->Right->Right = NULL;
break;
}
}
else
{
if (P->Left != NULL)
P = P->Left;
else
{
P->Left = (BinTree)malloc(sizeof(struct TNode));
P->Left->Data = X;
P->Left->Left = NULL;
P->Left->Right = NULL;
break;
}
}
}
}
return BST;
}
BinTree Delete(BinTree BST, ElementType X)
{
Position p;
ElementType t;
if (BST == NULL)
{
printf("Not Found\n");
return NULL;
}
else
{
if (X < BST->Data)
{
if (BST->Left == NULL)
{
printf("Not Found\n");
return BST;
}
else
{
BST->Left = Delete(BST->Left, X);
return BST;
}
}
else if (X > BST->Data)
{
if (BST->Right == NULL)
{
printf("Not Found\n");
return BST;
}
else
{
BST->Right = Delete(BST->Right, X);
return BST;
}
}
else
{
if (BST->Left == NULL && BST->Right == NULL)
{
free(BST);
return NULL;
}
else if (BST->Left == NULL && BST->Right != NULL)
{
p = BST;
BST = BST->Right;
free(p);
return BST;
}
else if (BST->Left != NULL && BST->Right == NULL)
{
p = BST;
BST = BST->Left;
free(p);
return BST;
}
else
{
t = FindMin(BST->Right)->Data;
BST->Data = t;
BST->Right = Delete(BST->Right, t);
return BST;
}
}
}
}
void PreOrderTraversal(BinTree T, int* a)
{
int i = 0;
Stack S;
S = CreateStack();
while (T != NULL || !IsEmpty(S))
{
if (T != NULL)
{
a[i] = T->Data;
++i;
Push(S, T);
T = T->Left;
}
else
{
T = Pop(S);
T = T->Right;
}
}
free(S);
}
void InOrderTraversal(BinTree T, int* a)
{
int i = 0;
Stack S;
S = CreateStack();
while (T != NULL || !IsEmpty(S))
{
if (T != NULL)
{
Push(S, T);
T = T->Left;
}
else
{
T = Pop(S);
a[i] = T->Data;
++i;
T = T->Right;
}
}
free(S);
}