1. 程式人生 > >二叉搜尋樹(建立及其遍歷等)

二叉搜尋樹(建立及其遍歷等)

題目描述

判斷兩序列是否為同一二叉搜尋樹序列

輸入描述:

開始一個數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;
}