L3-1 二叉搜索树的结构 (30 分)
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。(摘自百度百科)
给定一系列互不相等的整数,将它们顺次插入一棵初始为空的二叉搜索树,然后对结果树的结构进行描述。你需要能判断给定的描述是否正确。例如将{ 2 4 1 3 0 }插入后,得到一棵二叉搜索树,则陈述句如“2是树的根”、“1和4是兄弟结点”、“3和0在同一层上”(指自顶向下的深度相同)、“2是4的双亲结点”、“3是4的左孩子”都是正确的;而“4是2的左孩子”、“1和3是兄弟结点”都是不正确的。
输入格式:
输入在第一行给出一个正整数(),随后一行给出个互不相同的整数,数字间以空格分隔,要求将之顺次插入一棵初始为空的二叉搜索树。之后给出一个正整数(),随后行,每行给出一句待判断的陈述句。陈述句有以下6种:
A is the root
,即"A
是树的根";A and B are siblings
,即"A
和B
是兄弟结点";A is the parent of B
,即"A
是B
的双亲结点";A is the left child of B
,即"A
是B
的左孩子";A is the right child of B
,即"A
是B
的右孩子";A and B are on the same level
,即"A
和B
在同一层上"。
题目保证所有给定的整数都在整型范围内。
输出格式:
对每句陈述,如果正确则输出Yes
,否则输出No
,每句占一行。
输入样例:
5 2 4 1 3 0 8 2 is the root 1 and 4 are siblings 3 and 0 are on the same level 2 is the parent of 4 3 is the left child of 4 1 is the right child of 2 4 and 0 are on the same level 100 is the right child of 3
输出样例:
Yes Yes Yes Yes Yes No No No
ACcode:
#include<bits/stdc++.h> using namespace std; int l[900],r[900],dep[900],fa[900]; int tree[900]; int root; map<int,int>m; //&now 取地址不要忘记,加了取地址就不用return 了 void Insert(int& now,int f,int deep,int num){ if(now==-1){ now = num;//赋予的是节点号 fa[num] = f; dep[num] =deep; return ; } if(tree[num]<tree[now])//要比真实数据 Insert(l[now],now,deep+1,num); else Insert(r[now],now,deep+1,num); } int Is(int a,int b){ if(m.find(a)!=m.end()&&m.find(b)!=m.end()){ return 1; } return 0; } int main(){ int n; cin>>n; memset(l,-1,sizeof l); memset(r,-1,sizeof r); root = -1; for(int i=1;i<=n;i++){ cin>>tree[i]; Insert(root,-1,1,i); m[tree[i]] = i; //m 和 tree数组互为倒数 //树的节点存储的为下标,如root,fa,l,r等 //m存储为真实数据对应的节点号 //输入的是真实数据,所以调用fa是要转换为对应节点号 } cin>>n; for(int i=1;i<=n;i++){ int f = 0; int a,b; string tt; cin>>a; cin>>tt; if(tt=="is"){ cin>>tt>>tt; if(tt=="root"){ if(tree[root]==a&&m.find(a)!=m.end()){ f = 1; } } else if(tt=="parent"){ cin>>tt>>b; if(Is(a,b)&&fa[m[b]]==m[a]){ f = 1; } } else if(tt=="left"){ cin>>tt>>tt>>b; if(Is(a,b)&&fa[m[a]]==m[b]&&a<b){f=1;} } else{ cin>>tt>>tt>>b; if(Is(a,b)&&fa[m[a]]==m[b]&&a>b){f=1;} } } else { cin>>b>>tt>>tt; if(tt=="siblings"){ if(Is(a,b)&&fa[m[a]]==fa[m[b]]){f=1;} } else { cin>>tt>>tt>>tt; if(Is(a,b)&&dep[m[a]]==dep[m[b]])f=1; } } if(f)puts("Yes"); else puts("No"); } return 0; }
STL代码存档(不能AC):
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<ext/pb_ds/tree_policy.hpp> #include<ext/pb_ds/assoc_container.hpp> #include<algorithm> #define lli long long using namespace std; using namespace __gnu_pbds; void read(lli &n) { char c='+';lli x=0;bool flag=0; while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();} flag==1?n=-x:n=x; } tree<lli,null_type,std::less<lli>,splay_tree_tag,tree_order_statistics_node_update>st; int main() { ios::sync_with_stdio(0); lli T; lli ans,x,y; cin>>T; for(lli i=1;i<=T;i++) { //read(x);read(y); cin>>x>>y; if(x==1) st.insert((y<<20)+i); else if(x==2)st.erase(st.lower_bound(y<<20)); else if(x==3)printf("%lld\n",st.order_of_key(y<<20)+1); else { if(x==4)ans=*st.find_by_order(y-1); if(x==5)ans=*--st.lower_bound(y<<20); if(x==6)ans=*st.lower_bound((y+1)<<20); printf("%lld\n",ans>>20); } } return 0; }