二叉搜索树(建立及其遍历等)

题目描述

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

输入描述:

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

输出描述:

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

输入

2
567432
543267
576342
0

输出

YES
NO

方法一:利用链表建立二叉搜索树树并遍历

分析:(前序和中序遍历)或(中序和后序遍历)可以唯一确定一棵二叉树,而对二叉排序树而言,相同元素的二叉排序树中序遍历一定相同(为一个递增序列),而相同元素的不同二叉排序树使用前序遍历就可以发现不相同,所以只需要前序遍历两个二叉排序树,比较一下就可以判断

代码如下:

#include <stdio.h>
#include <string.h>
#include<math.h>
#include<stdlib.h>
typedef struct node{
    char data;
    struct node *lchild,*rchild;
}*tree;
int len,k;
void create(tree &head,char a[]){
    int i;
    node *p,*q,*pre;
    p=(node *)malloc(sizeof(node));
    p->data=a[0];
    p->lchild=p->rchild=NULL;
    head=p;
    for(i=1;i<len;i++){
        p=(node *)malloc(sizeof(node));
        p->data=a[i];
        p->lchild=p->rchild=NULL;
        q=head;
        while(q!=NULL){
            pre=q;
            if(a[i]>q->data)
                q=q->rchild;
            else if(a[i]<q->data)
                q=q->lchild;
        }
        if(a[i]>pre->data)
            pre->rchild=p;
        else if(a[i]<pre->data)
            pre->lchild=p;
    }
    return ;
}
void pre(node *p,char a[]){
    if(p!=NULL){
        a[k++]=p->data;
        pre(p->lchild,a);
        pre(p->rchild,a);
    }
}
int main(){
    int n,i;
    char a[12],b[12];
    while(scanf("%d",&n)!=EOF){
        if(n==0)
            break;
        getchar();
        tree head=NULL;
        scanf("%s",a);
        len=strlen(a);
        create(head,a);
        k=0;
        pre(head,a);
        while(n--){
            scanf("%s",b);
            tree head1=NULL;
            create(head1,b);
            k=0;
            pre(head1,b);
            int x=1;
            for(i=0;i<len;i++)
                if(a[i]!=b[i]){
                    x=0;
                    break;
                }

            if(x==1)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }

    return 0;
}

方法二:题目的数据量很小,所以直接数组模拟建树,为了比较的方便直接建成完全二叉树,这样就便于比较了,只要是相同位置必有相同的值,否则不是相同的二叉树

#include <stdio.h>
#include <string.h>
#include<math.h>
#include<stdlib.h>
int len,k;
void create(char a[],int c[]){
    int i,j;
    for(i=0;i<1024;i++)
        c[i]=-1;
    c[1]=a[0]-'0';
    for(i=1;i<len;i++){
        for(j=1;j<1024;){
            k=j;
            if(c[j]==-1){
                c[j]=a[i]-'0';
                break;
            }
            if(a[i]-'0'<c[j])
                j=2*j;
            else if(a[i]-'0'>c[j])
                j=2*j+1;
        }
    }
    return ;
}
int main(){
    int n,i;
    char a[12],b[12];
    int c[1030],d[1030];
    while(scanf("%d",&n)!=EOF){
        if(n==0)
            break;
        getchar();
        scanf("%s",a);
        len=strlen(a);
        create(a,c);
        while(n--){
            scanf("%s",b);
            create(b,d);
            int x=1;
            for(i=1;i<1024;i++)
                if(c[i]!=d[i]){
                    x=0;
                    break;
                }

            if(x==1)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }

    return 0;
}
#include <stdio.h>
#include <string.h>
#include<math.h>
#include<stdlib.h>
int len,k;
void create(char a[],char c[]){
    int i,j;
    for(i=0;i<1024;i++)
        c[i]='a';
    c[1]=a[0];
    for(i=1;i<len;i++){
        for(j=1;j<1024;){
            if(j>k) k=j;  //注意k值的变化
            if(c[j]=='a'){
                c[j]=a[i];
                break;
            }
            if(a[i]<c[j])
                j=2*j;
            else if(a[i]>c[j])
                j=2*j+1;
        }
    }
    return ;
}
int main(){
    int n,i;
    char a[12],b[12];
    char c[1030],d[1030];
    while(scanf("%d",&n)!=EOF){
        if(n==0)
            break;
        k=0;
        getchar();
        scanf("%s",a);
        len=strlen(a);
        create(a,c);
        while(n--){
            scanf("%s",b);
            create(b,d);
            int x=1;
            for(i=1;i<=k;i++)
                if(c[i]!=d[i]){
                    x=0;
                    break;
                }
            if(x==1)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }

    return 0;
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值