第四讲 树(中)

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;
}
posted @ 2017-05-10 23:48  VincentValentine  阅读(368)  评论(0编辑  收藏  举报