sixth(二叉排序树)!


二叉排序树就是中序遍历之后是有序的;

构造二叉排序树步骤如下;

插入法构造

 第二个结点 4 比 6 来的小 所以插入在 6 的左子树;

 第三个结点 8 比 6 来的大 所以插入在 6 的右子树;

第四个结点 5 比6 来得小 先进入左子树然后跟 4比较,

5 比4 大 所以插入在 4 的右子树;

 

以此类推 将要插入的结点先跟根结点比较, 比根结点大进入右子树 反之进入 左子树;

在跟进入的 左子树(右子树)的结点比较 方法同上;

直到没有结点了  在插入;  你给的排序最后的二叉排序树如下;




二叉排序树

Time Limit: 1000MS  Memory Limit: 65536KB
Problem Description

二叉排序树的定义是:或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 今天我们要判断两序列是否为同一二叉排序树

Input
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉排序树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉排序树。(数据保证不会有空树)
Output
 
Example Input
2
123456789
987654321
432156789
0
Example Output
NO
NO
 
 
  
  
01#include<bits/stdc++.h>
02using namespace std;
03typedef struct node
04{
05    char data;
06    struct node *l,*r;
07}*p;
08p root;
09int a,b;
10char pr[20],la[20];
11struct node* creat(p root,int ch)
12{
13    if(root==NULL)
14    {
15        root=new(node);
16        root->l=NULL;
17        root->r=NULL;
18        root->data=ch;
递归建立二叉排序树过程是不断的从root跟开始调用直到空为止然后按照左小右大的规则插入。
19    }
20    else
21    {
22 
23        if(ch < root->data)
24            root->l=creat(root->l,ch);
25        else
26            root->r=creat(root->r,ch);
27    }
递归时要注意前后的联系,每次都要进行root->l=creat(root->l,ch)的传递。
28    return root;
29}
30void pre(p tree)
31{
32if(tree!=NULL)
33{
34pr[a++]=tree->data;
35pre(tree->l);
36pre(tree->r);
37}
对顺序建立的数进行前序后序的遍历保存到数组中
38}
39void last(p tree)
40{
41if(tree!=NULL)
42{
43last(tree->l);
44last(tree->r);
45la[b++]=tree->data;
46}
47}
48int main()
49{
50    int n,i,j;
51    char str1[20],str2[20];
52    while(cin>>n)
53    {
54        root=NULL;
55        if(n==0)
56        break;
57        a=0;b=0;
58        cin>>str1;
59        for(i=0;str1[i]!='\0';i++)
60        root=creat(root,str1[i]);
61        pre(root);
62        pr[a]='\0';
数组存数完成之后记得把最后加上终止符号。
63        last(root);
64        la[b]='\0';
65        for(j=0;j<n;j++)
66        {
67        cin>>str2;
68        if(strcmp(pr,str2)==0||strcmp(la,str2)==0||strcmp(str1,str2)==0)
69        cout<<"YES"<<endl;
70        else
71        cout<<"NO"<<endl;
72        }
73        }
74    return 0;
75}
错误代码。。。。。。
#include<bits/stdc++.h> using namespace std; typedef struct node {     char data;     struct node *l,*r; }*p; char str1[1005],str2[1005]; int k,n,a,b; char mm[25],hh[25]; struct node* creat(p root,char ch) {     if(root==NULL)     {         root=new(node);         root->l=NULL;         root->r=NULL;         root->data=ch;     }     else     {         if(ch < root->data)             root->l=creat(root->l,ch);         else             root->r=creat(root->r,ch);     }     return root; } void mid(struct node *root) {     if(root)     {         mid(root->l);         mm[a++]=root->data;         mid(root->r);     } } void mid2(struct node *root) {     if(root)     {         mid2(root->l);         hh[b++]=root->data;         mid2(root->r);     } } int main() {     int n;     struct node*root;     while(cin>>n)     {     memset(mm,0,sizeof(mm));         k=1;         a=0;         root=NULL;         cin>>str1;         for(int k=0;k!='\0';k++)             root=creat(root,str1[k]);         mid(root);         mm[a]='\0';         while(n--)         {         memset(hh,0,sizeof(hh));         root=NULL;         b=0;         cin>>str2;         for(int j=0;j!='\0';j++)             root=creat(root,str2[j]);         mid2(root);         hh[b]='\0';         if(strcmp(mm,hh)==0)         cout<<"YES"<<endl;         else         cout<<"NO"<<endl;         }     }     return 0; }

迷失の搜索树

Time Limit: 1000MS  Memory Limit: 65536KB
Problem Description

小璐在机缘巧合之下获得了一个二叉搜索树,这个二叉搜索树恰好有n个节点,每个节点有一个权值,每个节点的权值都在[1,n]这个区间内,并且两两不相同,真是优美的性质啊

但是命运的不公又让她失去了这个二叉搜索树

幸运的是,她还记得自己丢失的二叉搜索树的前序遍历序列。

在丢了二叉搜索树之后,小璐无比想念她的这个树的后序遍历

那么问题来了,聪明的你在知道这个二叉搜索树的前序遍历的序列的情况下,能帮她找到这个二叉搜索树的后序遍历嘛?

Input

 多组输入,以文件结尾

每组数据第一行为一个整数n,代表这个二叉搜索树的节点个数(1<=n<=100)

接下来一行n个整数,代表这个二叉搜索树的前序遍历序列

Output

输出n个整数

表示这个二叉树的后序遍历序列

Example Input
5
4 2 1 3 5
Example Output
1 3 2 5 4
Hint

 二叉查找树是一棵空树,或者是具有下列性质的二叉树:

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值

若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值

它的左、右子树也分别为二叉排序树


#include<bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    struct node *lch,*rch;
};
int k,n;
struct node* creat(struct node *root,int ch)
{
    if(root==NULL)
    {
        root=new(node);
        root->lch=NULL;
        root->rch=NULL;
        root->data=ch;
    }
    else
    {
        if(ch < root->data)
            root->lch=creat(root->lch,ch);
        else
            root->rch=creat(root->rch,ch);
    }
    return root;
}
void hou(struct node *root)
{
    if(root)
    {
        hou(root->lch);
        hou(root->rch);
        if(k==1)
        {
            cout<<root->data;
            k++;
        }
        else
        cout<<" "<<root->data;
        }
}
int main()
{
    int n,i;
    struct node*root;
    while(cin>>n)
    {
        k=1;
        root=NULL;
        while(n--)
        {
            cin>>i;
            root=creat(root,i);
        }
        hou(root);
        cout<<endl;
    }
    return 0;
}

一直前序遍历就可以建树。根据根左右的特点。再根据二叉排序树的定义可以直接根据左右节点构建。

数据结构实验之查找一:二叉排序树

Time Limit: 400MS  Memory Limit: 65536KB
Problem Description

对应给定的一个序列可以唯一确定一棵二叉排序树。然而,一棵给定的二叉排序树却可以由多种不同的序列得到。例如分别按照序列{3,1,4}和{3,4,1}插入初始为空的二叉排序树,都得到一样的结果。你的任务书对于输入的各种序列,判断它们是否能生成一样的二叉排序树。

Input

输入包含若干组测试数据。每组数据的第1行给出两个正整数N (n < = 10)和L,分别是输入序列的元素个数和需要比较的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列生成一颗二叉排序树。随后L行,每行给出N个元素,属于L个需要检查的序列。 简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。

Output

对每一组需要检查的序列,如果其生成的二叉排序树跟初始序列生成的二叉排序树一样,则输出"Yes",否则输出"No"。

Example Input
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
Example Output
Yes
No
No

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    struct node *lch,*rch;
};
int k,n,a[15],b[15];
struct node* creat(struct node *root,int ch)
{
    if(root==NULL)
    {
        root=new(node);
        root->lch=NULL;
        root->rch=NULL;
        root->data=ch;
    }
    else
    {


        if(ch < root->data)
            root->lch=creat(root->lch,ch);
        else
            root->rch=creat(root->rch,ch);
    }
    return root;
}
void mid(struct node *root)
{
    if(root)
    {
        mid(root->lch);
        a[k++]=root->data;
        mid(root->rch);
    }
}
void mid2(struct node *root)
{
    if(root)
    {
        mid(root->lch);
        b[k++]=root->data;
        mid(root->rch);
    }
}
int main()
{
    int n,i,x;
    struct node*root;
    while(cin>>n>>x)
    {
        k=1;
        root=NULL;
        while(n--)
        {
            cin>>i;
            root=creat(root,i);
        }
        mid(root);
        while(x--)
        {
        int flag=0;
        k=1;
        root=NULL;
        while(n--)
        {
            cin>>i;
            root=creat(root,i);
        }
        mid2(root);
        for(int j=1;j<=n;j++)
        if(a[j]!=b[j])
        {
        flag=1;
        break;
        }
        if(flag==0)
        cout<<"Yes"<<endl;
        else
        cout<<"No"<<endl;
        }
    }
    return 0;
}
没有输出的数据。
#include<bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    struct node *lch,*rch;
};
int k,n,flag;
struct node* creat(struct node *root,int ch)
{
    if(root==NULL)
    {
        root=new(node);
        root->lch=NULL;
        root->rch=NULL;
        root->data=ch;
    }
    else
    {


        if(ch < root->data)
            root->lch=creat(root->lch,ch);
        else
            root->rch=creat(root->rch,ch);
    }
    return root;
}
void mid(struct node *root1,struct node *root2)
{
    if(root1&&root2)
    {
        mid(root1->lch,root2->lch);
        if(root1->data!=root2->data)
        {
        flag=1;
        return ;
        }
        mid(root1->rch,root2->rch);
    }
}
int main()
{
    int n,i,x;
    struct node*root1=new node,*root2=new node;
    while(cin>>n>>x)
    {
        root1=NULL;
        while(n--)
        {
            cin>>i;
            root1=creat(root1,i);
        }
        while(x--)
        {
        flag=0;
        root2=NULL;
        while(n--)
        {
            cin>>i;
            root2=creat(root2,i);
        }
        mid(root1,root2);
        if(flag==0)
        cout<<"Yes"<<endl;
        else
        cout<<"No"<<endl;
        }
    }
    return 0;
}、
Accepted
#include<bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    struct node *lch,*rch;
};
int k,n,flag;
struct node* creat(struct node *root,int ch)
{
    if(root==NULL)
    {
        root=new(node);
        root->lch=NULL;
        root->rch=NULL;
        root->data=ch;
    }
    else
    {




        if(ch < root->data)
            root->lch=creat(root->lch,ch);
        else
            root->rch=creat(root->rch,ch);
    }
    return root;
}
void mid(struct node *root1,struct node *root2)
{
    if(root1&&root2)
    {




        mid(root1->lch,root2->lch);
        if(root1->data!=root2->data)
        {
        flag=1;
        return ;
        }
        mid(root1->rch,root2->rch);
    }
}
int main()
{
    int n,i,x;
    struct node*root1=new node,*root2=new node;
    while(cin>>n>>x)
    {
        root1=NULL;
        for(int t1=0;t1<n;t1++)
        {
            cin>>i;
            root1=creat(root1,i);
        }
        for(int t2=0;t2<x;t2++)
        {
        flag=0;
        root2=NULL;
        for(int t3=0;t3<n;t3++)
        {
            cin>>i;
            root2=creat(root2,i);
        }
        mid(root1,root2);
        if(flag==0)
        cout<<"Yes"<<endl;
        else
        cout<<"No"<<endl;
        }
    }
    return 0;
}
思路:判断两个序列能否构成同一颗二叉排序树,只要前序或后续遍历有一个相同就行,因为前序或后续有一个相同就说明他们的组成元素相同,又因为二叉排序树的中序遍历都是相同的。所以要么是确定了前序中序,要么是确定了后序中序这样就能确定两个二叉树排序树想同了。

提示

一定要记住每一步的回溯,搞清楚根节点是什么,根据二叉树的左右子树的高度差来判断进行什么样的调整

1.调整方法

(1)插入点位置必须满足二叉查找树的性质,即任意一棵子树的左结点都小于根结点,右结点大于根结点

(2)找出插入结点后不平衡的最小二叉树进行调整,如果是整个树不平衡,才进行整个树的调整。

2.调整方式

(1)LL型

LL型:插入位置为左子树的左结点,进行向右旋转

由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1变为2,成为不平衡的最小二叉树根结点。此时A结点顺时针右旋转,旋转过程中遵循“旋转优先”的规则,A结点替换D结点成为B结点的右子树,D结点成为A结点的左孩子。
(2)RR型
RR型:插入位置 为右子树的右孩子,进行向左旋转
由于在A的右子树C的右子树插入了结点F,A的平衡因子由-1变为-2,成为不平衡的最小二叉树根结点。此时,A结点逆时针左旋转,遵循“旋转优先”的规则,A结点替换D结点成为C的左子树,D结点成为A的右子树。
(3)LR型
LR型:插入位置为 左子树的右孩子,要进行两次旋转,先左旋转(RR型),再右旋转(LL型);第一次最小不平衡子树的根结点先不动,调整插入结点所在的子树,第二次再调整最小不平衡子树。
由于在A的左子树B的右子树上插入了结点F,A的平衡因子由1变为了2,成为不平衡的最小二叉树根结点。第一次旋转A结点不动,先将B的右子树的根结点D向左上旋转提升到B结点的位置,然后再把该D结点向右上旋转提升到A结点的位置。
(4)RL型
RL型:插入位置为右子树的左孩子,进行两次调整,先右旋转再左旋转;处理情况与LR类似。

数据结构实验之查找二:平衡二叉树

Time Limit: 400MS  Memory Limit: 65536KB
Problem Description

根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。

Input

输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。

Output

输出平衡二叉树的树根。

Example Input
5
88 70 61 96 120
Example Output
70



  
  
001#include<bits/stdc++.h>
002typedef int Elemtype;
003struct node
004{
005    Elemtype data;
006    int d;
007    struct node *lchild,*rchild;
008};
009int max(int x,int y)
010{
011    return x>y ? x:y;
012}
013int Deep(struct node *head)
014{
015    if (!head)
016        return -1;
017    else return head->d;
018}
019struct node *LL(struct node *head)//右旋
020{
021    struct node *p = head->lchild;
022    head->lchild = p->rchild;
023    p->rchild = head;
024    p->d = max(Deep(p->lchild),Deep(p->rchild))+1;
025    head->d = max(Deep(head->lchild),Deep(head->rchild))+1;
026    return p;
027}
028struct node *RR(struct node *head)//左旋
029{
030    struct node *p = head->rchild;
031    head->rchild = p->lchild;
032    p->lchild = head;
033    p->d = max(Deep(p->lchild),Deep(p->rchild))+1;
034    head->d = max(Deep(head->lchild),Deep(head->rchild))+1;
035    return p;
036}
037 
038 
039struct node *LR(struct node *head)
040{
041    head->lchild = RR(head->lchild);//先做左旋
042    return LL(head);//在做右旋
043}
044 
045 
046struct node *RL(struct node *head)
047{
048    head->rchild = LL(head->rchild);//先做右旋
049    return RR(head);//在做左旋
050}
051struct node *Creat(struct node *head,int x)
052{
053    if (head == NULL)
054    {
055        head = (struct node *)malloc (sizeof (struct node));
056        head->data = x;
057        head->d = 0;
058        head->rchild = head->lchild = NULL;
059    }
060    else if (head->data > x)
061    {
062        head->lchild = Creat(head->lchild,x);
063        if (Deep(head->lchild)-Deep(head->rchild)>1)
064        {
065            if (head->lchild->data > x)
066                head = LL(head);
067            else
068                head = LR(head);
069        }
070    }
071    else if (head->data < x)
072    {
073        head->rchild  = Creat(head->rchild,x);
074        if (Deep(head->rchild)-Deep(head->lchild)>1)
075        {
076            if (head->rchild->data > x)
077                head = RL(head);
078            else
079                head = RR(head);
080        }
081    }
082    head->d = max(Deep(head->lchild),Deep(head->rchild))+1;
083    return head;
084}
085int main()
086{
087    int n,m;
088    scanf ("%d",&n);
089    struct node *head = NULL;
090    for (int i=0; i<n; i++)
091    {
092        scanf ("%d",&m);
093        head = Creat(head,m);
094    }
095    printf ("%d\n",head->data);
096    return 0;
097}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了python应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值