第四讲 树(中)
04-树4:是否同一棵二叉搜索树
Description:
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
Input:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N≤10和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
Output:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
SampleInput:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
SampleOutput:
Yes
No
No
Codes:
//#define LOCAL
#include <cstdio>
#include <cstdlib>
typedef struct tN *tr;
struct tN { int d, f; tr l, r; };
tr newN(int d) {
tr T = (tr)malloc(sizeof(tN));
T->d = d, T->f = 0, T->l = T->r = NULL;
return T;
}
tr insert(tr T, int d) {
if(!T) T = newN(d);
else {
if(d > T->d) T->r = insert(T->r, d);
else T->l = insert(T->l, d);
}
return T;
}
tr build(int N) {
tr T; int i, d;
scanf("%d", &d);
T = newN(d);
for(i=1; i<N; ++i) { scanf("%d", &d); T = insert(T, d); }
return T;
}
bool check(tr T, int d) {
if(T->f) {
if(d < T->d) return check(T->l, d);
else if(d > T->d) return check(T->r, d);
} else {
if(d == T-> d) { T->f = 1; return true; }
else return false;
}
}
int same(tr T, int N) {
int d, i, f = 0;
scanf("%d", &d);
if(d != T->d) f = 1;
else T->f = 1;
for(i=1; i<N; ++i) {
scanf("%d", &d);
if(!f && !check(T, d)) f = 1;
}
if(f) return 0;
else return 1;
}
void reset(tr T) {
if(T->l) reset(T->l);
if(T->r) reset(T->r);
T->f = 0;
}
void freeT(tr T) {
if(T->l) freeT(T->l);
if(T->r) freeT(T->r);
free(T);
}
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
int i, N, L; tr T;
scanf("%d", &N);
while(N) {
scanf("%d", &L);
T = build(N);
for(i=0; i<L; ++i) {
if(same(T, N)) printf("Yes\n");
else printf("No\n");
reset(T);
}
freeT(T); scanf("%d", &N);
}
return 0;
}
PAT-1066:Root of AVL Tree.
Description:
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
Output:
For each test case, print ythe root of the resulting AVL tree in one line.
SampleInput1:
5
88 70 61 96 120
SampleOutput1:
70
SampleInput2:
7
88 70 61 96 120 90 65
SampleOutput2:
88
Codes:
//#define LOCAL
#include <cstdio>
#include <algorithm>
using namespace std;
struct N {
int v, w; N *l, *r;
N(int vs, N* ls, N* rs) : v(vs), l(ls), r(rs), w(0) {}
};
N *nil = new N(0, NULL, NULL); N *h = nil;
void leftR(N *&h) {
N *t = h->r; h->r = t->l; t->l = h;
h = t; h->l->w = max(h->l->r->w, h->l->l->w)+1;
h->w = max(h->r->w, h->l->w)+1;
}
void rightR(N *&h) {
N *t = h->l; h->l = t->r; t->r = h;
h = t; h->r->w = max(h->r->r->w, h->r->l->w)+1;
h->w = max(h->r->w, h->l->w)+1;
}
void insert(N *&h, int v) {
if(h == nil) h = new N(v, nil, nil);
else if(v > h->v) {
insert(h->r, v);
if(h->r->w-h->l->w == 2) {
if(v > h->r->v) leftR(h);
else { rightR(h->r); leftR(h); }
}
} else {
insert(h->l, v);
if(h->l->w-h->r->w == 2) {
if(v <= h->l->v) rightR(h);
else { leftR(h->l); rightR(h); }
}
}
h->w = max(h->l->w, h->r->w)+1;
}
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
int a, n;
scanf("%d", &n);
while(n--) {
scanf("%d", &a);
insert(h, a);
}
printf("%d\n", h->v);
return 0;
}
PAT-1064:Complete Binary Search Tree.
Description:
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
Both the left and right subtrees must also be binary search trees.
A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.
Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.
Input:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.
Output:
For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
SampleInput:
10
1 2 3 4 5 6 7 8 9 0
SampleOutput:
6 3 8 1 5 7 9 0 2 4
Codes:
//#define LOCAL
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define M 1010
int i, n, A[M], B[M]; vector<int> pO;
void pT(int r) {
if(r > n) return;
pT(2*r); pO.push_back(r); pT(2*r+1);
}
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
scanf("%d", &n);
for(i=0; i<n; ++i) scanf("%d", &A[i]);
sort(A, A+n); pT(1);
for(i=0; i<pO.size(); ++i) B[pO[i]] = A[i];
for(i=1; i<n; ++i) printf("%d ", B[i]);
printf("%d\n", B[n]);
return 0;
}