c++二叉树寒假特训题目(1)答案你

大家好,我是Joseph,今天给大家写了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题单的。

注:此问为我朋友所写,侵权必删(我没看)。

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值