判断二叉树是否相同

给定一个插入序列就可以唯一确定一棵二叉搜索树,但是不同的插入序列也可能构成相同的二叉搜索树。例如按2,1,3和2,3,1插入空的二叉搜索树得到的结果都是一样的。
输入要求,先输入两个整数,第一个整数代表树的结点个数,第二个整数代表,除了样例外,还要输入的进行比较的序列的个数。
1.可以不建树进行判断。先比较第一个数是否相同,若相同,则将后序序列中比第一个数小的数字分成一堆放在该数字之前,将比该数大的数字放在后面,在分别判断新形成的两个序列,递归的操作,本质上也相当于树。
2.本题采用的解法是,建一棵树,在判别其它数列是否与该树一致。

解题思路:
1.搜索树表示
2.建搜索树T
3.判断序列是否与搜索树一致

一 设置数据结构

typedef struct Treenode *Tree;
struct Treenode
{
    int v;
    Tree left;
    Tree right;
    int flag;   //用于判断是否相同时做标记。
};

二 程序框架搭建

1.读入节点个数和要判断的序列个数N和L
2.创建树T
3.依据树T判断接下的L个序列形成的树是否相同并输出结果。


完整代码:

#include <stdio.h>
#include <stdlib.h>
typedef struct Treenode *Tree;
struct Treenode
{
    int v;
    Tree left;
    Tree right;
    int flag;       //用于后序的比较过程,初始为0.
};
Tree Newcode(int V)  //创建树的节点部分
{
    Tree T=(Tree)malloc(sizeof(struct Treenode));
    T->v=V;
    T->left=T->right=NULL;
    T->flag=0;
    return T;
}
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;//判断一个节点符合后将该节点的flag标记为1,下一个输入的元素会执行上半条语句,根据大小判断其左右子树,相当于查找的过程
            return 1;
        }
        return 0;
    }
}
Tree insert(Tree T,int V)  //插入后序元素的函数
{
    if(!T)T=Newcode(V);
    else
    {
        if(V>T->v)
            T->right=insert(T->right,V);
        else
            T->left=insert(T->left,V);
    }
    return T;
}
Tree MakeTree(int N)  //创建一个标准树
{
    Tree T;
    int i,V;
    scanf("%d",&V);
    T=Newcode(V);   //创建根节点部分
    for(i=1;i<N;i++)
    {
        scanf("%d",&V);
        T=insert(T,V);    //依次插入后序的元素
    }
    return T;
}
int judge(Tree T,int N)  //判断函数不能写成遇到不符合的元素就退出的形式,要判断完全部该序列的元素,否则会影响下一个序列的判断。
{
    int i,V,flag=0;
    scanf("%d",&V);    //先输入要比较的序列的第一个元素,作为树的根节点
    if(V!=T->v)flag=1;  //若根都不同直接让flag为1,说明不符合。
    else T->flag=1;    
    for(i=1;i<N;i++)
    {
        scanf("%d",&V);   //再输入序列中后序的原素。
        if((!flag)&&(!check(T,V)))flag=1; //依次检查输入的元素,假如flag还是0的情况下,check检测到了不符合的值,flag也会被标记为1,不符合。
    }
    if(flag)return 0;
    else return 1;
}
void ResetT(Tree T)//将树的flag清楚为0
{
    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);
}
int main()
{
    int N,L,i;
    Tree T;
    scanf("%d",&N);
    while(N){
    scanf("%d",&L);
    T=MakeTree(N);
    for(i=0;i<L;i++)
    {
        if(judge(T,N))printf("Yes\n");
        else {printf("No\n");}
        ResetT(T);
    }
    FreeTree(T);
    scanf("%d",&N);  //继续输入下一组数据。
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值