04-树4 是否同一棵二叉搜索树

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode *Tree;
struct TreeNode {
    int V;
    Tree Left,Right;
    int flag; //设立被访问的标记,0未被访问,1被访问
};

Tree MakeTree(int N);
Tree NewNode(int V);
Tree Insert(Tree T, int V);
int Judge(Tree T, int N);
int check(Tree T, int V);
void ResetT(Tree T);
void FreeTree(Tree T);

int main() {

    //对每组数据
    //读入N L
    //根据第一行序列建树 T
    //依据树T分别判断后面的 L 序列是否能与 T 形成同一搜索树并输出Yes或No
    int N,L,i;
    Tree T;
    scanf("%d",&N);
    while(N) { //N=0输入序列结束
        scanf("%d",&L);
        T=MakeTree(N); //读入后面的N个树,建树T
        for(i=0; i<L; i++) { //判断L个序列是否能建成与树T一致的二叉排序树
            if(Judge(T,N)) //读入一个序列的N个树并判断
                printf("Yes\n");
            else
                printf("No\n");
            ResetT(T); //清除T中flag标记,来进行下一次循环
        }
        FreeTree(T); //一组数据处理完,就可以把T树free掉
        scanf("%d",&N);
    }
    return 0;
}

Tree MakeTree(int N) {
    Tree T;
    int V,i;
    scanf("%d",&V);
    T=NewNode(V); //先申请一个树的根结点
    for(i=1; i<N; i++) { //此处 i=1!!!!
        scanf("%d",&V);
        T=Insert(T,V);
    }
    return T;
}

Tree NewNode(int V) {
    Tree T=(Tree)malloc(sizeof(struct TreeNode));
    T->V=V;
    T->Left=T->Right=NULL;
    T->flag=0;
    return T;
}

Tree Insert(Tree T, int V) {
    if(!T)
        T=NewNode(V);
    else {
        if(V>T->V)
            T->Right=Insert(T->Right, V);
        else
            T->Left=Insert(T->Left, V);
    }
    return T;
}

int Judge(Tree T, int N) { // 1相同,0不同
    int i,V;
    int flag=0; //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(!check(T,V)) return0;
        //当发现序列中某个数与T不一致,必须把序列后面的全部读完
        if((!flag)&&(!check(T,V)))flag=1;
    }
    if(!flag) return 1;
    else return 0;
}

int check(Tree T, int V) { //如果每次搜索经过的结点在之前的搜索均出现过,则一致
    if(T->flag) {
        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;
    }
}

void ResetT(Tree T) { //清除T中结点flag的标记
    if(T->Left) ResetT(T->Left);
    if(T->Right) ResetT(T->Right);
    T->flag=0;
}

void FreeTree(Tree T) { //释放一组T的空间
    if(T->Left) FreeTree(T->Left);
    if(T->Right) FreeTree(T->Right);
    free(T);
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值