5-4 是否同一棵二叉搜索树 (25分)
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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
这个思路其实很容易想到,但在实现的过程中遇到了一点点困难,就是在check函数里进行递归后会返回刚进函数返回的那个值,
开始一直认为return后就会跳出递归,事实证明我太年轻了。用过全局变量,但是不太对。网上大多数博客都是用的mooc上老师的
那种方法,看了半天终于有位兄弟用了这种方法(万分感谢!),下面check函数的代码就是他的思路。
建两个树的方法:
#include <stdio.h> #include <stdlib.h> struct TNode{ int num; struct TNode *left; struct TNode *right; }; typedef struct TNode *BinTree; BinTree insert(BinTree BT,int number)/*建树*/ { if(BT == NULL) { BT = (BinTree)malloc(sizeof(struct TNode)); BT->num = number; BT->left = BT->right = NULL; } else { if(number > BT->num) { BT->right = insert(BT->right,number); } else if(number < BT->num) { BT->left = insert(BT->left,number); } } return BT; } bool check(BinTree BT1,BinTree BT2)/*比较两个树*/ { if(BT1 && BT2 && (BT1->num == BT2->num))/*当当前的两个根结点都不空,并且数据相等*/ { if(check(BT1->left,BT2->left)&&check(BT1->right,BT2->right))/*递归的调用check函数,当当前根结点的左右为true才返回true*/ { return true; } else { return false; } } else if(BT1 == NULL && BT2 == NULL)/*有一个不空就返回false,就相当于有一个树有这个结点,另一个没有*/ { return true; } else { return false; } } int main(void) { BinTree BT1 = NULL; BinTree BT2 = NULL; int n,l; int Tree1,Tree2; while(1) { scanf("%d",&n); if(n == 0) { break; } scanf("%d",&l); BT1 = NULL;/*判断完一个树之后,重新弄一个树*/ for(int i = 0; i < n; i++) { scanf("%d",&Tree1); BT1 = insert(BT1,Tree1); } for(int i = 0; i < l; i++) { BT2 = NULL;/*判断完一个树之后,重新弄一个树*/ for(int i = 0; i < n; i++) { scanf("%d",&Tree2); BT2 = insert(BT2,Tree2); } if(check(BT1,BT2) == true) { printf("Yes\n"); } else { printf("No\n"); } } } return 0; }
建一个树的方法:#include <stdio.h> #include <stdlib.h> struct TNode{ int num; struct TNode *left; struct TNode *right; int flag; }; typedef struct TNode *BinTree; BinTree NewNode(int v) { BinTree BT = (BinTree)malloc(sizeof(struct TNode)); BT->num = v; BT->left = BT->right = NULL; BT->flag = 0; return BT; } BinTree insert(BinTree BT,int v) { if(!BT) { BT = NewNode(v); } else { if(v > BT->num) { BT->right = insert(BT->right,v); } else if(v < BT->num) { BT->left = insert(BT->left,v); } } return BT; } BinTree MakeTree(int n) { int v; BinTree BT; scanf("%d",&v); BT = NewNode(v); for(int i = 1; i < n; i++) { scanf("%d",&v); BT = insert(BT,v); } return BT; } int check(BinTree BT,int v) { if(BT->flag) { if(v < BT->num) { return check(BT->left,v); } else if(v > BT->num) { return check(BT->right,v); } else return 0; } else { if(v == BT->num) { BT->flag = 1; return 1; } else return 0; } } int Judge(BinTree BT, int n) { int v,flag = 0; scanf("%d",&v); if(v != BT->num) { flag = 1; } else { BT->flag = 1; } for(int i = 1; i < n; i++) { scanf("%d",&v); if((!flag) && (!check(BT,v)) ) { flag = 1; } } if(flag) { return 0; } else return 1; } void ResetT(BinTree BT) { if(BT->left) ResetT(BT->left); if(BT->right) ResetT(BT->right); BT->flag = 0; } void FreeTree(BinTree BT) { if(BT->left) FreeTree(BT->left); if(BT->right) FreeTree(BT->right); free(BT); } int main(void) { BinTree BT; int n,l; scanf("%d",&n); while(n) { scanf("%d",&l); BT = MakeTree(n); for(int i = 0; i < l; i++) { if(Judge(BT,n)) { printf("Yes\n"); } else { printf("No\n"); } ResetT(BT); } FreeTree(BT); scanf("%d",&n); } return 0; }