关于二叉排序树的总结

 由于近几天学习了二叉排序树,对于一些题目有一些个人的见解,随手写下这篇博文,以供大家参考

二叉排序树的概念一定要弄懂: 

 

、二叉排序树的做法是首先建立一颗树,然后先序(中序,后序)遍历输出,如果相同则是同一棵树

、建树的时候应该分两种情况:第一是一开始是一颗空树直接插入,第二是如果小于当前节点就把它插到左子树上

      否则就放到右子树上;

 关键代码:

struct node *creat(struct node *root, char x)
{
    if(root == NULL)
    {
        root = (struct node *)malloc(sizeof(struct node));
        root->l = NULL;
        root->r = NULL;
        root->data = x;
    }
    else
    {
        if(x > root->data)
        {
            root->r = creat(root->r,x);
        }
        else root->l = creat(root->l,x);
    }
    return root;
};

     

、判断是否是同一棵二叉排序树,只需要将作为参照的字符串按照先序遍历,只不过这里 不再是输出了,而是把它存到一个数组中,要判断的也是一样,存在一个数组中最后比较 这两个数组比较即可。

关键代码;

void headcreat(struct node *root)
{
    if(root)
    {
        a[k++] = root->data;
        headcreat(root->l);
        headcreat(root->r);
    }
}
void headcreat1(struct node *root)
{
    if(root)
    {
        b[k++] = root->data;
        headcreat1(root->l);
        headcreat1(root->r);
    }
}

  参考完整代码:

     

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char a[100], b[100];
int k;
struct node
{
    char data;
    struct node *l, *r;
};
/*建立二叉排序树的时候要分两种情况,第一如果是空树直接写出,
  第二,如果不是空树还要分两种情况,(1)如果要插入的节点小于根节点、
  就把它放在左子树,反之
*/
struct node *creat(struct node *root, char x)
{
    if(root == NULL)
    {
        root = (struct node *)malloc(sizeof(struct node));
        root->l = NULL;
        root->r = NULL;
        root->data = x;
    }
    else
    {
        if(x > root->data)
        {
            root->r = creat(root->r,x);
        }
        else root->l = creat(root->l,x);
    }
    return root;
};
/*判断是否是同一棵二叉排序树,只需要将作为参照的字符串按照先序遍历,只不过这里
  不再是输出了,而是把它存到一个数组中,要判断的也是一样,存在一个数组中最后比较
  这两个数组比较即可
*/
void headcreat(struct node *root)
{
    if(root)
    {
        a[k++] = root->data;
        headcreat(root->l);
        headcreat(root->r);
    }
}
void headcreat1(struct node *root)
{
    if(root)
    {
        b[k++] = root->data;
        headcreat1(root->l);
        headcreat1(root->r);
    }
}
int main()
{
    struct node *root;
    int n, len, i;
    char str1[100], str2[100], x;
    while(~scanf("%d",&n)&&n)
    {
        k = 0;
        root = NULL;// 要把root置0;
        getchar();
        scanf("%s",str1);
         len = strlen(str1);
         for(i = 0;i < len;i++)
         {
             x = str1[i];
             root = creat(root,x);
         }
        headcreat(root);
        a[len] = '\0'; //因为字符串是以'\0'作为结束的标志,但是上面没有结束的标志
                       //所以要把最后一个值为结束,下面的也是这样
        while(n--)
        {
            k = 0;
            root = NULL;// 要把root置0;
             scanf("%s",str2);
             for(i = 0;i < len;i++)
             {
                 x = str2[i];
                 root = creat(root,x);
             }
             headcreat1(root);
             b[k] = '\0';
             if(strcmp(a,b) == 0)
                printf("YES\n");
             else printf("NO\n");
        }
    }
    return 0;
}

 


  

其实关于二叉排序树SDUT OJ 上的题目有写相同的,只不过具体的细节不同罢了,比如说:

https://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2563/pid/3373

 此题与上面的区别是输入的数字,二上面那个是字符串

 main函数的部分代码:

int main()
{
    struct node *root;
    int n,i, m, x, p, q;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        k = 0;
        root = NULL;// 要把root置0;
        for(i = 0;i < n;i++)
        {
            scanf("%d",&x);
            root = creat(root,x);
        }
        headcreat(root);
        while(m--)
        {
            int flag = 1;
            k = 0;
            root = NULL;// 要把root置0;
             for(i = 0;i < n;i++)
             {
                 scanf("%d",&x);
                 root = creat(root,x);
             }
             headcreat1(root);
             for(p = 0;p < n;p++)
             {
                 for(q = p+1;q < n;q++)
                 {
                     if(a[p] == b[q])
                     {
                         flag = 0;
                     }
                 }
             }
            if(flag)
                printf("Yes\n");
             else printf("No\n");
        }
    }
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值