大家好,我是周曦,今天给大家写了c++二叉树寒假特训题目(1)的答案。
题目传送门
答案
二叉树存储
思路
存储部分可以用满二叉树的性质,设深度为k,那么一共有2的k次方减1个数,最多是1024个。计算与输出部分因为是满二叉树,我们可以计算一个节点在第几层,如果一个节点大于2ⁿ⁻¹,那么他是在最后一层,没有子节点就输出none,否则输出下标为x*2和x*2+1的点。注意要换行。
代码
#include<bits/stdc++.h>
using namespace std;
int n,x;
int a[1024];
int main(){
cin>>n;
for(int i=1;i<=pow(2,n)-1;i++){
cin>>a[i];
}
cin>>x;
if(x>=pow(2,n-1)){
cout<<"none";
}else{
cout<<a[x*2]<<" "<<a[x*2+1];
}
return 0;
}
淘汰赛
思路
这一题我是用了一种类似动态规划的做法:先建一个2ⁿ*2的数组,输入部分在2ⁿ到2ⁿ*2-1,接来看图(以n=3为例):
也就是将下标为i*2和i*2+1的打擂台,而亚军就是下标为2和3中的最小值。
代码
#include<bits/stdc++.h>
using namespace std;
map<string,int> m;
int n,x;
int a[10001];
int t[10001];
int main(){
cin>>n;
for(int i=pow(2,n);i<=pow(2,n)*2-1;i++){
cin>>a[i];
t[a[i]]=i-pow(2,n)+1;
}
for(int i=pow(2,n)-1;i>=1;i--){
a[i]=max(a[i*2],a[i*2+1]);
//cout<<a[i]<<" ";
}
cout<<t[min(a[2],a[3])];
return 0;
}
前序遍历
思路
这题很简单,一个结构体ok,dfs顺序记住,先输出,再遍历做儿子,最后遍历右儿子,直接上代码。
代码
#include<iostream>
using namespace std;
int n;
struct node{
int l,r;
char z;
}ans[10001];
void dfs(int i){
if(i!=0){
cout<<ans[i].z;
dfs(ans[i].l);
dfs(ans[i].r);
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>ans[i].z>>ans[i].l>>ans[i].r;
dfs(1);
return 0;
}
中序遍历与后序遍历
说明
只需要把上一题dfs里的顺序改一下就行,此处不多讲。
子树的大小
思路
首先一个循环求深度,在判断得了,太水了,直接上代码。
代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,cnt=1;
cin>>m>>n;
int x=m;
while(x*2+1<=n){
cnt++;
x=x*2+1;
}
int ans=pow(2,cnt)-1;
int l=m*pow(2,cnt);
if(l>n) cout<<ans;
else cout<<ans+(n-l+1);
return 0;
}
结点的查找
思路
看上去yyds,实际上想到就是道水题,全代码只有两个循环,一个来输入,一个求k层理论上的的最左和最右的节点编号。首先输入,一个大while包着全部,再一个while求k层理论上的的最左和最右的节点编号,接下来判断,如果左子节点编号大于n,那直接输出EMPTY,如果左右子节点都小于等于n,输出从左子节点到右子节点中的所有编号,换行,如果右子节点大于n但左子节点小于等于n,输出左子节点到n。
代码(你们最喜欢的copy环节!)
#include<bits/stdc++.h>
using namespace std;
int n,k;
int main(){
while(cin>>n>>k){
int bas=1,vol=1;
for(int i=1;i<=k-1;i++){
bas*=2;
vol*=2;
vol+=1;
}
if(bas>n){
cout<<"EMPTY"<<endl;
}else{
if(vol<=n){
for(int i=bas;i<=vol;i++){
cout<<i<<" ";
}
cout<<endl;
}else{
if(vol>n&&bas<=n){
for(int i=bas;i<=n;i++){
cout<<i<<" ";
}
cout<<endl;
}
}
}
}
return 0;
}
总结
这次的题真的水,不知道是题里掺了点水还是水里掺了点题,第一题主要考了概念,对二叉树不熟的是无法确定要输入几次和最后的判断条件。第二题动态规划和二叉树基本概念学得好也是不成问题的。前中后序遍历用我给的模板写是有手就行。子树的大小有些难,我用了十分钟才搞定的。最后一题想通了也蛮简单了。
总的来说,只要以前的算法和二叉树概念过关,是可以轻松AK题单的。