• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

Vigil

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

MOOC数据结构PTA-04-树4 是否同一棵二叉搜索树

题目

给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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
结尾无空行

题目理解

采用根据输入,建立一棵树,然后将比较序列在树上查找,当查找到序列之前没有过的节点时,说明此方式与本树不同。
注意的是在判断是否在之前出现过的节点时,不能判断到未出现的就即时返回,因为后边还有输入,要把输入全部接受才返回。

代码

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
    int v;
    struct node *left, *right;
    int flag;  //标志域,1代表被访问过
} Node, *Tree;

//函数声明
Tree MakeTree(int N);
int Judge(Tree T, int N);
Tree NewNode(int V);
Tree Insert(Tree T, int V);
int check(Tree T, int V);
void ResetT(Tree T);
void FreeTree(Tree T);

int main() {
    int N, L, i;
    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);  //清除T中标记flag
        }
        FreeTree(T);
        scanf("%d", &N);
    }
    return 0;
}

Tree MakeTree(int N) {
    Tree T;
    int i, V;

    scanf("%d", &V);
    T = NewNode(V);
    for (i = 1; i < N; i++) {
        scanf("%d", &V);
        T = Insert(T, V);
    }
    return T;
}
Tree NewNode(int V) {
    Tree T = (Tree)malloc(sizeof(Node));
    T->v = V;
    T->left = NULL;
    T->right = NULL;
    T->flag = 0;
    return T;
}
Tree Insert(Tree T, int V) {
    if (T == NULL)
        T = NewNode(V);
    else {
        if (V > T->v)
            T->right = Insert(T->right, V);
        else
            T->left = Insert(T->left, V);
    }
    return T;
}

int check(Tree T, int V) {
    // flag = 1表示被访问过,继续下一个判断
    if (T->flag == 1) {
        if (V < T->v)
            return check(T->left, V);
        else if (V > T->v)
            return check(T->right, V);
        else
            return 0;
    } else {
        if (V == T->v) {
            T->flag = 1;
            return 1;
        } else
            return 0;
    }
}
int Judge(Tree T, int N) {
    // flag: 0代表目前还一致,1代表已经不一致了
    int i, V, flag = 0;

    scanf("%d", &V);
    if (V != T->v)
        flag = 1;
    else
        T->flag = 1;
    for (i = 1; i < N; i++) {
        scanf("%d", &V);
        if ((flag == 0) && (0 == check(T, V)))
            flag = 1;
    }
    if (flag)
        return 0;
    else
        return 1;
}
void ResetT(Tree T) {
    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);
}

image

posted on 2021-08-09 23:27  VigilYang  阅读(76)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3