A - 二叉搜索树 HDU - 3791

判断两序列是否为同一二叉搜索树序列

Input

开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。 
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。 
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。

Output

如果序列相同则输出YES,否则输出NO 

Sample Input

2
567432
543267
576342
0

Sample Output

YES
NO

题目意思很清楚就是判断第一行的序列与其他几行的比较看是否是同一搜索二叉树;

我用的就是最好想到的方法,就是建立一个搜索二叉树,然后比较前序遍历和中序遍历

一般前序,中序,后序遍历要三个中有两个相同才能确定是否为为一个搜索二叉树。

要是不知道什么是搜索二叉树可以看看这个视频,里面讲了搜索二叉树的构建,和前序中序遍历。

概述树:https://www.bilibili.com/video/av10472337

搜索二叉树的构建和前序,中序遍历的实现:https://www.bilibili.com/video/av10472353

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char c[100],sq[100],s1q[100],sz[100],s1z[100];
int h;
typedef struct note
{
    int data;               //树节点的值
    struct note *left;      //左节点
    struct note *right;     //右节点
} Note;
typedef struct
{
    Note *root;           //整个树,便于后面写程序
} Tree;


void insert(Tree *tree,int value)   //构建树的函数
{

    Note* note=malloc(sizeof(Note));      //实现动态内存 c++条件下会报错。
    note -> data = value;             //初始化根节点
    note -> left = NULL;
    note -> right= NULL;

    if(tree -> root== NULL )         //如果下面没有跟子节点了
    {
        tree -> root = note;         //构建树
    }
    else
    {
        Note* temp = tree ->root;   //定义一个中间值
        while(temp !=NULL)          //直到树建立完毕后结束
        {
            if(value < temp ->data) //值小于根节点分到左子节点上
            {
                if(temp -> left ==NULL) //刚好左左子节点是空的
                {
                    temp ->left = note;  
                    return;
                }
                else                    //左子节点不为空,temp变成自己的左子节点
                {
                    temp =temp ->left;
                }
            }
            else                     //这是大于的情况为右子节点,和上面的一样。
            {
                if(temp -> right ==NULL)
                {
                    temp -> right =note;
                    return ;
                }
                else
                {
                    temp =temp -> right;
                }
            }

        }
    }
}
void perorder(Note *note)      //前序遍历
{
    if(note !=NULL)            //如果是空就返回
    {
        //printf("%d\n",note -> data);
        c[h++]=note ->data+'0';     //存入根节点
        perorder(note -> left);     //递归左子节点
        perorder(note -> right);    //递归右子节点
    }
}
void inrorder(Note *note)          //中序遍历
{
    if(note!=NULL)                 
    {
        inrorder(note -> left);   //先左子节点
        c[h++]=note ->data+'0';   //然后根
        inrorder(note -> right);  //后右子节点
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        getchar();
        Tree tree;          //定义树结构体
        char b[100];
        int i,j;
        gets(b);
        tree.root=NULL;
        h=0;
        for(j=0; j<strlen(b); j++)
        {
            insert(&tree,b[j]-'0');  //创建第一行 的树
        }
        perorder(tree.root);         //前序遍历第一行的树
        c[h]=0;
        strcpy(sq,c);                //前序遍历的结果存到 sq 数组中
        h=0;
        for(j=0; j<strlen(b); j++)
        {
            insert(&tree,b[j]-'0');  
        }
        inrorder(tree.root);        //中序遍历树,并存到  sz 数组中
        c[h]=0;
        strcpy(sz,c);
        for(i=1; i<=n; i++)        //输入后面的几行数字
        {
            gets(b);
            tree.root=NULL;
            h=0;
            for(j=0; j<strlen(b); j++)
            {
                insert(&tree,b[j]-'0');  //建立树
            }
            perorder(tree.root);        //前序遍历树并与存到 slq 数组中
            c[h]=0;
            strcpy(s1q,c);
            h=0;
            h=0;
            for(j=0; j<strlen(b); j++)
            {
                insert(&tree,b[j]-'0');
            }
            inrorder(tree.root);        //中序遍历树,并存到  slz 数组中
            c[h]=0;
            strcpy(s1z,c);
            if(strcmp(sq,s1q)==0 && strcmp(sz,s1z) ==0) //和第一行的比较,如果前序和中序都相同输出  YES
                printf("YES\n");
            else
                printf("NO\n");
        }
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值