NO
NO
01 | #include<bits/stdc++.h> |
11 | struct node* creat(p root, int ch) |
递归建立二叉排序树过程是不断的从root跟开始调用直到空为止然后按照左小右大的规则插入。
24 | root->l=creat(root->l,ch); |
26 | root->r=creat(root->r,ch); |
递归时要注意前后的联系,每次都要进行root->l=creat(root->l,ch)的传递。
对顺序建立的数进行前序后序的遍历保存到数组中
51 | char str1[20],str2[20]; |
59 | for (i=0;str1[i]!= '\0' ;i++) |
60 | root=creat(root,str1[i]); |
数组存数完成之后记得把最后加上终止符号。
68 | if ( strcmp (pr,str2)==0|| strcmp (la,str2)==0|| strcmp (str1,str2)==0) |
#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
Example Input
Example Output
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
#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
Example Output
001 | #include<bits/stdc++.h> |
007 | struct node *lchild,*rchild; |
013 | int Deep( struct node *head) |
019 | struct node *LL( struct node *head) |
021 | struct node *p = head->lchild; |
022 | head->lchild = p->rchild; |
024 | p->d = max(Deep(p->lchild),Deep(p->rchild))+1; |
025 | head->d = max(Deep(head->lchild),Deep(head->rchild))+1; |
028 | struct node *RR( struct node *head) |
030 | struct node *p = head->rchild; |
031 | head->rchild = p->lchild; |
033 | p->d = max(Deep(p->lchild),Deep(p->rchild))+1; |
034 | head->d = max(Deep(head->lchild),Deep(head->rchild))+1; |
039 | struct node *LR( struct node *head) |
041 | head->lchild = RR(head->lchild); |
046 | struct node *RL( struct node *head) |
048 | head->rchild = LL(head->rchild); |
051 | struct node *Creat( struct node *head, int x) |
055 | head = ( struct node *) malloc ( sizeof ( struct node)); |
058 | head->rchild = head->lchild = NULL; |
060 | else if (head->data > x) |
062 | head->lchild = Creat(head->lchild,x); |
063 | if (Deep(head->lchild)-Deep(head->rchild)>1) |
065 | if (head->lchild->data > x) |
071 | else if (head->data < x) |
073 | head->rchild = Creat(head->rchild,x); |
074 | if (Deep(head->rchild)-Deep(head->lchild)>1) |
076 | if (head->rchild->data > x) |
082 | head->d = max(Deep(head->lchild),Deep(head->rchild))+1; |
089 | struct node *head = NULL; |
090 | for ( int i=0; i<n; i++) |
093 | head = Creat(head,m); |
095 | printf ( "%d\n" ,head->data); |