2024/2/1 备战蓝桥杯 3-3 二叉树

目录

二叉树的遍历

B3642 二叉树的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

完全二叉树的权值

0完全二叉树的权值 - 蓝桥云课 (lanqiao.cn)

美国血统 American Heritage

P1827 [USACO3.4] 美国血统 American Heritage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

求先序排列

P1030 [NOIP2001 普及组] 求先序排列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)


二叉树的遍历

B3642 二叉树的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:

明白二叉树三种遍历方式:

先序遍历:根,左,右

中序遍历:左,根,右

后续遍历:左,右,根

完整代码:

#include <bits/stdc++.h>
#define int long long
const int N = 1e6+10;
int p[N];
struct node
{
    int v;
    int ls,rs;
}t[N];
void preorder(int u)//先序遍历
{
    if(u!=0)
    {
        std::cout<<t[u].v<<" ";
        preorder(t[u].ls);
        preorder(t[u].rs);
    }
}
void midorder(int u)//中序遍历
{
    if(u!=0)
    {
        midorder(t[u].ls);
        std::cout<<t[u].v<<" ";
        midorder(t[u].rs);
    }
}
void postorder(int u)//后续遍历
{
    if(u!=0)
    {
        postorder(t[u].ls);
        postorder(t[u].rs);
        std::cout<<t[u].v<<" ";
    }
}
signed main()
{
    int n;
    std::cin >> n;
    for(int i = 1;i <= n;i ++)
    {
        int x,y;
        std::cin >> x >> y;
        t[i].v=i;
        t[i].ls=x;
        t[i].rs=y;
    }
    preorder(1);
    std::cout<<"\n";
    midorder(1);
    std::cout<<"\n";
    postorder(1);
    std::cout<<"\n";
    return 0;
}

完全二叉树的权值

0完全二叉树的权值 - 蓝桥云课 (lanqiao.cn)

思路:用一个数组存每一层二叉树的权值,再比较哪一层的权值最大

ceil(log(i+1)/log(2)):这个公式用于计算二叉树的深度

完整代码:

#include <bits/stdc++.h>
#define int long long
const int N = 1e5+10;
int sum[N];
signed main()
{
    int n;
    std::cin >> n;
    for(int i = 1;i <= n;i ++)
    {
        int x;
        std::cin >> x;
        int d=ceil(log(i+1)/log(2));
        sum[d]+=x;
    }
    int maxx=-999;
    int ans=1;
    for(int i = 1;i <= N;i ++)
    {
        if(sum[i]>maxx)
        {
            maxx=sum[i];
            ans=i;
        }
    }
    std::cout<<ans;
    return 0;
}

美国血统 American Heritage

P1827 [USACO3.4] 美国血统 American Heritage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:递归

其他在代码的注释里面

这道题是输出后续遍历,后序是左右根,所以根在最后输出

完整代码:

#include <bits/stdc++.h>
#define int long long
std::string pre,inor;
void work(std::string pre,std::string inor)
{
    if(pre.empty()) //如果序列空了,就结束
        return;
    char root=pre[0];//取前序遍历的根节点
    int k = inor.find(root);//找到中序序列中根节点的位置
    pre.erase(pre.begin());//删除前序序列中的根节点
    std::string leftpre=pre.substr(0,k);
    std::string rightpre=pre.substr(k);
    std::string leftinor=inor.substr(0,k);
    std::string rightinor=inor.substr(k+1);
    work(leftpre,leftinor);
    work(rightpre,rightinor);
    std::cout<<root;
}
signed main()
{
    std::cin >> inor >> pre;
    work(pre,inor);
    return 0;
}

求先序排列

P1030 [NOIP2001 普及组] 求先序排列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:和前面一题类似,用递归

这道题是求先序排列

先序的顺序是根左右,所以得到根之后要先输出,在递归

完整代码:

#include <bits/stdc++.h>
#define int long long
std::string inor, last;

void work(std::string inor, std::string last) {
    if (last.empty())
        return;
    char root = last[last.size()-1];
    std::cout << root;
    last.pop_back();
    //last.erase(last[last.size()-1]);
    int k = inor.find(root);
    std::string leftinor = inor.substr(0, k);
    std::string rightinor = inor.substr(k + 1);
    std::string leftlast = last.substr(0, k);
    std::string rightlast = last.substr(k);
    work(leftinor, leftlast);
    work(rightinor, rightlast);
   // std::cout<<root;
}
signed main() {
    std::cin >> inor >> last;
    work(inor, last);
    return 0;
}

  • 22
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我们需要定义二叉树的节点结构体: ```c struct TreeNode { char val; // 存储操作符或数字 struct TreeNode* left; struct TreeNode* right; }; ``` 然后,我们定义一个函数 `buildTree(char* s)`,将表达式字符串 `s` 存入二叉树中: ```c struct TreeNode* buildTree(char* s) { struct TreeNode* root = NULL; struct TreeNode* cur = NULL; struct TreeNode* stack[100]; int top = -1; int num = 0; // 存储数字,用于处理多位数字的情况 int flag = 1; // 标记当前数字的正负性,默认为正数 for (int i = 0; s[i] != '\0'; i++) { if (s[i] >= '0' && s[i] <= '9') { // 处理数字 num = num * 10 + s[i] - '0'; } else { // 处理操作符 if (flag == -1) { num = -num; flag = 1; } if (cur == NULL) { // 第一个节点 cur = (struct TreeNode*)malloc(sizeof(struct TreeNode)); cur->val = num; root = cur; } else if (cur->left == NULL) { // 左子节点 cur->left = (struct TreeNode*)malloc(sizeof(struct TreeNode)); cur->left->val = num; cur = cur->left; } else if (cur->right == NULL) { // 右子节点 cur->right = (struct TreeNode*)malloc(sizeof(struct TreeNode)); cur->right->val = num; cur = cur->right; } else { // 如果当前节点已经有左右子节点,则需要回溯到最近的未满的父节点 while (cur->right != NULL) { cur = stack[top--]; } cur->right = (struct TreeNode*)malloc(sizeof(struct TreeNode)); cur->right->val = num; cur = cur->right; } num = 0; // 清零num,准备处理下一个数字 if (s[i] == '-') { flag = -1; } else { cur->val = s[i]; } } // 将当前节点入栈 if (cur != NULL && (cur->val == '+' || cur->val == '-' || cur->val == '*' || cur->val == '/')) { stack[++top] = cur; } } if (flag == -1) { num = -num; } cur->val = num; // 处理最后一个数字 return root; } ``` 接着,我们定义一个函数 `evalTree(struct TreeNode* root)`,求二叉树表达式的值: ```c int evalTree(struct TreeNode* root) { if (root == NULL) { return 0; } if (root->left == NULL && root->right == NULL) { // 叶子节点为数字 return root->val; } int leftVal = evalTree(root->left); int rightVal = evalTree(root->right); switch (root->val) { case '+': return leftVal + rightVal; case '-': return leftVal - rightVal; case '*': return leftVal * rightVal; case '/': return leftVal / rightVal; default: return 0; } } ``` 最后,我们可以使用以下代码进行测试: ```c int main() { char s[] = "1+2*3-4/5"; struct TreeNode* root = buildTree(s); int res = evalTree(root); printf("%s=%d\n", s, res); return 0; } ``` 输出结果为: ``` 1+2*3-4/5=6 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值