来自MOOC数据结构
这个题先构建了一个树,再将要检查的序列进行遍历这颗树
不得不说,好的代码是你一眼就能get这个思路,慢慢也能看懂,就是写不出来这么好的代码。
要学的还有很多啊
#include <stdio.h>
#include <stdlib.h>
typedef struct T {
int v;
struct T* Left, * Right;
int flag;//记录这个树的结点是否被检查过
}*Tree;
Tree NewNode(int V) {
Tree T = (Tree)malloc(sizeof(struct T));
T->flag = 0; T->Left = NULL; T->Right = NULL; T->v = V;
return T;
}
Tree Insert(Tree T, int V) {
if (!T) {
T = NewNode(V); //若为空,则创建一个新的结点存放V
}
else if (V < T->v) {
T->Left = Insert(T->Left, V);
}
else {
T->Right = Insert(T->Right, V);
}
return T; //1.左(右)子结点不空时,仍将其返回给父节点的左(右)指针 2.为空时,创建一个结点返回
}
Tree MakeTree(int N){
Tree T;
int i, V; //V代表输入的结点的元素,要将这N个元素插入到树中
scanf("%d", &V);
T = NewNode(V); //创建一个新的根结点
for (i = 1; i < N; i++) {
scanf("%d", &V);
T = Insert(T, V);
}
return T;
}
int check(Tree T, int V) { //这个被检查元素在T的对应位置时返回1
if (T->flag) { //这个结点被检索过
if (V < T->v) {
return check(T->Left, V);
}
else if (V > T->v) {
return check(T->Right, V);
}
else { //V == T->v
return 0; //已近被检索过得结点在检查时还是有与这个点的值相同,一定不满足 即被检查序列一定有两个相同的值
}
}
else {
if (V == T->v) {
T->flag = 1;
return 1;
}
else {
return 0;
}
}
}
int Judge(Tree T, int N) { //检查序列与构建的树是否相同
int i, V, flag = 0; //记录是否被检查元素与原树对应位置相同,1代表不同
scanf("%d", &V);
if (V != T->v) { //检查根节点
flag = 1;
}
else {
T->flag = 1;
}
//输入一个就判断一下,为了不影响下一个检查序列的输入,在这个序列未输入完之前,即使发现了不为一棵树,也不能退出,要等输入结束才可以... (妙啊)
for (i = 1; i < N; i++) {
scanf("%d", &V);
if (!flag && !check(T, V))
flag = 1;
}
if (flag)
return 0;
else
return 1;
}
void ResetT(Tree T) { //将树的flag置0
if (T->Left) ResetT(T->Left);
if (T->Right) ResetT(T->Right);
T->flag = 0;
}
void FreeTree(Tree T) { //将创建的树释放
if (T->Left) FreeTree(T->Left);
if (T->Right) FreeTree(T->Right);
free(T);
}
int main() {
int N, L;//N代表这个树有几个结点 L代表有几个树与原树检查
Tree T;
scanf("%d", &N);
while (N) {
scanf("%d", &L);
T = MakeTree(N); //创建这颗树
for (int i = 0; i < L; i++) {
if (Judge(T, N)) //对检查的序列进行输入和检查
printf("Yes\n");
else
printf("No\n");
ResetT(T);
}
FreeTree(T);
scanf("%d", &N);
}
return 0;
}