当前位置: 首页 > news >正文

数据结构C语言描述9(图文结合)--二叉树和特殊书的概念,二叉树“最傻瓜式创建”与前中后序的“递归”与“非递归遍历”

前言

  • 这个专栏将会用纯C实现常用的数据结构和简单的算法;
  • 有C基础即可跟着学习,代码均可运行;
  • 准备考研的也可跟着写,个人感觉,如果时间充裕,手写一遍比看书、刷题管用很多,这也是本人采用纯C语言实现的原因之一;
  • 欢迎收藏 + 关注,本人将会持续更新。

文章目录

  • 树相关概念
    • 什么是二叉树
      • 二叉树定义
      • 基本概念
      • 基本形态
      • 二叉树性质
        • 性质1
        • 性质2
        • 性质3
        • 性质4
        • 性质五
    • 特殊二叉树
      • 满二叉树
      • 完全二叉树
  • 二叉树创建与遍历
    • 树创建
    • 树遍历
      • 前序
        • 递归
        • 非递归
      • 中序
        • 递归
        • 非递归
      • 后序
        • 递归
        • 非递归
    • 总代码

树相关概念

什么是二叉树

二叉树定义

二叉树是n (n≥0)个结点的有限集合

  • 每个节点最多有两个子节点,分别称为左子节点和右子节点。
  • 左子节点和右子节点可以为空
  • 二叉树的子树也是二叉树。

基本概念

  • 节点的度:一个节点含有的子树的个数称为该节点的度
  • 叶节点度为0的节点称为叶节点
  • 分支节点度不为0的节点,又称为非终端节点
  • 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点,又称为双亲结点
  • 子节点:一个节点含有的子树的根结点称为该节点的子节点,又称为孩子节点
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点
  • 树的度:一棵树中,最大的节点的度称为树的度
  • 节点的层次从根节点开始定义,根为第1层,根的子节点为第2层,以此类推
  • 树的高度或深度:树中节点的最大层次
  • 堂兄弟节点双亲在同一层的节点互为堂兄弟
  • 节点的祖先:从根到该节点所经分支上的所有节点
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙

基本形态

在这里插入图片描述

二叉树性质

性质1

二叉树第k (k>=1)层上至多有2k–1个结点。

思考题

若二叉树具有第k层的结点,那么第k层结点数的取值范围是多少?[1, 2k-1]

性质2

高度为h (h>=0)的二叉树至多有2h - 1个结点

思考题

高度为h的二叉树的结点数范围?

证明:高度为h的二叉树共有h层,第k层节点数范围为[1, 2k-1] ,故可知,高度为h的二叉树至少具有: ∑ k = 1 h 1 = h \sum _{k=1}^{h} 1=h k=1h1=h个节点;高度为h的二叉树至多具有 ∑ k = 1 h 2 k − 1 = 2 0 + 2 1 + . . . + 2 h − 1 = 2 h − 1 \sum ^{h}_{k=1}2^{k-1}=2^0+2^1+...+2^{h-1}=2^h-1 k=1h2k1=20+21+...+2h1=2h1
∑ k = 1 h 2 k − 1 = 2 0 + 2 1 + . . . + 2 h − 1 = 2 h − 1 \sum ^{h}_{k=1}2^{k-1}=2^0+2^1+...+2^{h-1}=2^h-1 k=1h2k1=20+21+...+2h1=2h1

性质3

设二叉树叶子结点数为n0,度为2的结点数为n2,则有:n0= n2+ 1。

性质4

结点数为n的完全二叉树的高度为: log ⁡ 2 n \log_2{n} log2n + 1或 log ⁡ 2 ( n + 1 ) \log_2{(n+1)} log2(n1)

性质五

给有n个结点的完全二叉树按层次编号,对于编号为i的结点:

  • 可计算i结点的双亲结点的编号
    • 若i = 1,则无双亲
    • 否则双亲编号为 i 2 \frac i 2 2i
  • 可计算i结点的左孩子结点的编号
    • 若2*i > n,则无左孩子
    • 否则其左孩子编号为2*i
  • 可计算i结点的右孩子结点的编号
    • 若2*i+1> n,则无右孩子
    • 否则其右孩子编号为2*i+1

特殊二叉树

满二叉树

  • 深度为h且具有2h-1个结点的二叉树
  • 每一层都容纳了该层所能容纳的最大结点数结点的二叉树
  • 没有度数为1的结点,且叶子结点均分布在最大层的二叉树

在这里插入图片描述

思考题

深度为h的满二叉树

  • 结点总数为? 2h - 1
  • 叶子结点数为? 2h-1
  • 度为1的结点数为?0
  • 度为2的结点数为?2h-1-1

具有n个结点的满二叉树

  • 有多少个叶子?(n + 1) / 2
  • 有多少个度为2的结点?(n - 1) / 2

完全二叉树

  • 除去最大层是一棵满二叉树
  • 除去最大层是一棵满二叉树

在这里插入图片描述

完全二叉树的几个非常有趣的特点:

  • 除去最大层是一棵满二叉树
  • 最大层上的结点向左充满
  • 叶子只可能分布在最大层和次大层上。
  • 度为1的结点至多有1个。
  • 一棵满二叉树一定是一棵完全二叉树,而一棵完全二叉树不一定是一棵满二叉树。
  • 对于具有相同结点数的二叉树而言,完全二叉树的高度一定是其中最小的

思考题

高度为h的完全二叉树的结点范围?[ 2k-1, 2k-1]

具有n个结点的二叉树的高度最小值为多少?高度最大值为多少? [ log ⁡ 2 n \log_2{n} log2n+1, n]

  • 完全二叉树最小: log ⁡ 2 n \log_2{n} log2n+1
  • 一层只有一个结点最大:n

二叉树创建与遍历

树创建

节点封装,二叉树,封装就需要封装两个孩子

typedef struct TreeNode {char data;struct TreeNode* LChild;struct TreeNode* RChild;
}TreeNode;TreeNode* create_node(char data)
{TreeNode* new_node = (TreeNode*)calloc(1, sizeof(TreeNode));assert(new_node);new_node->data = data;return new_node;
}

🚸 创建,这里采用“最傻瓜式”创建,如下代码所示:

// 傻瓜式建立树
void create_tree(TreeNode* parent, TreeNode* lChild, TreeNode* rChild)
{// 父亲不为 NULL 即可assert(parent);parent->LChild = lChild;parent->RChild = rChild;
}// 创建如下:
int main()
{// 一个一个创建节点TreeNode* a = create_node('a');   TreeNode* c = create_node('c');TreeNode* d = create_node('d');TreeNode* s = create_node('s');TreeNode* h = create_node('h');TreeNode* e = create_node('e');TreeNode* b = create_node('b');TreeNode* v = create_node('v');TreeNode* m = create_node('m');// 连接create_tree(a, c, d);   // a为跟节点create_tree(c, s, h);create_tree(d, e, b);create_tree(s, NULL, v);create_tree(h, NULL, NULL);create_tree(e, m, NULL);create_tree(b, NULL, NULL);return 0;
}

树遍历

前序

遍历顺序:左中右,动画如下所示(ppt制作):

在这里插入图片描述

递归
// 递归前序
void preorder_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}printf("%c ", root->data);preorder_recursion(root->LChild);preorder_recursion(root->RChild);
}
非递归

借助栈辅助

// 迭代前序遍历
// 注意一点:节点入栈顺序,与出栈顺序
void preorder_travel(TreeNode* root)
{assert(root);// 准备栈TreeNode* stack[1024] = { 0 };int top = -1;stack[++top] = root;while (top != -1) {TreeNode* temp = stack[top];top--;printf("%c ", temp->data);if (temp->RChild != NULL) stack[++top] = temp->RChild;if (temp->LChild != NULL) stack[++top] = temp->LChild;}
}

中序

遍历顺序:中左右

在这里插入图片描述

递归
// 递归中序
void mid_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}mid_recursion(root->LChild);printf("%c ", root->data);mid_recursion(root->RChild);
}
非递归

要注意:还有一个指针跟着栈走

// 中序,回退靠栈
// 核心:cur与栈配合,维护cur指针
void mid_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* cur = root;while (cur != NULL || top != -1) {if (cur != NULL) {stack[++top] = cur;cur = cur->LChild;}else {TreeNode* t = stack[top];top--;printf("%c ", t->data);cur = t->RChild;}}
}

后序

遍历顺序:左右中

在这里插入图片描述

递归
// 递归后序
void last_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}last_recursion(root->LChild);last_recursion(root->RChild);printf("%c ", root->data);
}
非递归

和前序遍历一样,维护一个栈

// 后序
// 核心:pre指针、cur指针,以及什么时候pre 与 cur指针相遇,以及为什么弹出后cur = NULL,pre = cur;
// 动画:想清楚如果一个节点要打印,则情况是什么,pre一直在模拟左、右、中节点
void last_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* used = NULL;TreeNode* cur = root;while (cur != NULL || top != -1) {while (cur) {stack[++top] = cur;cur = cur->LChild;}cur = stack[top];if (cur->RChild == NULL || cur->RChild == used) {printf("%c ", cur->data);top--;used = cur;cur = NULL;}else {cur = cur->RChild;}}
}

总代码

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>typedef struct TreeNode {char data;struct TreeNode* LChild;struct TreeNode* RChild;
}TreeNode;TreeNode* create_node(char data)
{TreeNode* new_node = (TreeNode*)calloc(1, sizeof(TreeNode));assert(new_node);new_node->data = data;return new_node;
}// 傻瓜式建立树
void create_tree(TreeNode* parent, TreeNode* lChild, TreeNode* rChild)
{// 父亲不为 NULL 即可assert(parent);parent->LChild = lChild;parent->RChild = rChild;
}// 递归前序
void preorder_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}printf("%c ", root->data);preorder_recursion(root->LChild);preorder_recursion(root->RChild);
}// 递归中序
void mid_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}mid_recursion(root->LChild);printf("%c ", root->data);mid_recursion(root->RChild);
}// 递归后序
void last_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}last_recursion(root->LChild);last_recursion(root->RChild);printf("%c ", root->data);
}// 迭代前序遍历
// 注意一点:节点入栈顺序,与出栈顺序
void preorder_travel(TreeNode* root)
{assert(root);// 准备栈TreeNode* stack[1024] = { 0 };int top = -1;stack[++top] = root;while (top != -1) {TreeNode* temp = stack[top];top--;printf("%c ", temp->data);if (temp->RChild != NULL) stack[++top] = temp->RChild;if (temp->LChild != NULL) stack[++top] = temp->LChild;}
}// 中序,回退靠栈
// 核心:cur与栈配合,维护cur指针
void mid_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* cur = root;while (cur != NULL || top != -1) {if (cur != NULL) {stack[++top] = cur;cur = cur->LChild;}else {TreeNode* t = stack[top];top--;printf("%c ", t->data);cur = t->RChild;}}
}// 后序
// 核心:pre指针、cur指针,以及什么时候pre 与 cur指针相遇,以及为什么弹出后cur = NULL,pre = cur;
// 动画:想清楚如果一个节点要打印,则情况是什么,pre一直在模拟左、右、中节点
void last_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* used = NULL;TreeNode* cur = root;while (cur != NULL || top != -1) {while (cur) {stack[++top] = cur;cur = cur->LChild;}cur = stack[top];if (cur->RChild == NULL || cur->RChild == used) {printf("%c ", cur->data);top--;used = cur;cur = NULL;}else {cur = cur->RChild;}}
}int main()
{// 一个一个创建节点TreeNode* a = create_node('a');   TreeNode* c = create_node('c');TreeNode* d = create_node('d');TreeNode* s = create_node('s');TreeNode* h = create_node('h');TreeNode* e = create_node('e');TreeNode* b = create_node('b');TreeNode* v = create_node('v');TreeNode* m = create_node('m');// 连接create_tree(a, c, d);   // a为跟节点create_tree(c, s, h);create_tree(d, e, b);create_tree(s, NULL, v);create_tree(h, NULL, NULL);create_tree(e, m, NULL);create_tree(b, NULL, NULL);printf("递归前序: \n");preorder_recursion(a);    printf("\n递归中序: \n");mid_recursion(a);printf("\n递归后序: \n");last_recursion(a);printf("\n迭代前序: \n");preorder_travel(a);printf("\n迭代中序: \n");mid_travel(a);printf("\n迭代后序: \n");last_travel(a);return 0;
}

相关文章:

数据结构C语言描述9(图文结合)--二叉树和特殊书的概念,二叉树“最傻瓜式创建”与前中后序的“递归”与“非递归遍历”

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法&#xff1b;有C基础即可跟着学习&#xff0c;代码均可运行&#xff1b;准备考研的也可跟着写&#xff0c;个人感觉&#xff0c;如果时间充裕&#xff0c;手写一遍比看书、刷题管用很多&#xff0c;这也是本人采用纯C语言…...

CSS——2.书写格式一

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><!--css书写中&#xff1a;--><!--1.css 由属性名:属性值构成--><!--style"color: red;font-size: 20px;&quo…...

Elasticsearch 创建索引 Mapping映射属性 索引库操作 增删改查

Mapping Type映射属性 mapping是对索引库中文档的约束&#xff0c;有以下类型。 text&#xff1a;用于分析和全文搜索&#xff0c;通常适用于长文本字段。keyword&#xff1a;用于精确匹配&#xff0c;不会进行分析&#xff0c;适用于标签、ID 等精确匹配场景。integer、long…...

【NLP高频面题 - 分布式训练篇】ZeRO主要为了解决什么问题?

【NLP高频面题 - 分布式训练篇】ZeRO主要为了解决什么问题&#xff1f; 重要性&#xff1a;★★ 零冗余优化器技术由 DeepSpeed 代码库提出&#xff0c;主要用于解决数据并行中的模型冗余问题&#xff0c;即每张 GPU 均需要复制一份模型参数。 ZeRO的全称是Zero Redundancy …...

kubernetes-循序渐进了解coredns

文章目录 概要基础知识Kubernetes 集群中对对象名称的 DNS 流量解析 Kubernetes 集群外的名称的 DNS 流量CoreDNS 如何确定向哪个本地 DNS 请求解析&#xff1f;修改 CoreDNS 的配置 概要 CoreDNS 是 Kubernetes 的核心组件之一。只有在 Kubernetes 集群中安装了 容器网络接口…...

mysql8 从C++源码角度看 客户端发送的sql信息 mysql服务端从网络读取到buff缓存中

MySQL 8 版本中的客户端-服务器通信相关&#xff0c;特别是在接收和解析网络请求的数据包时。以下是对代码各个部分的详细解释&#xff0c;帮助您更好地理解这些代码的作用。 代码概述 这段代码主要负责从网络读取数据包&#xff0c;它包含了多个函数来处理网络数据的读取、缓…...

pygame飞机大战

飞机大战 1.main类2.配置类3.游戏主类4.游戏资源类5.资源下载6.游戏效果 1.main类 启动游戏。 from MainWindow import MainWindow if __name__ __main__:appMainWindow()app.run()2.配置类 该类主要存放游戏的各种设置参数。 #窗口尺寸 #窗口尺寸 import random import p…...

【Vim Masterclass 笔记08】第 6 章:Vim 中的文本变换及替换操作 + S06L20:文本的插入、变更、替换,以及合并操作

文章目录 Section 6&#xff1a;Transforming and Substituting TextS06L21 Inserting, Changing, Replacing, and Joining1 定位到行首非空字符&#xff0c;并启用插入模式2 在紧挨光标的下一个字符位置启动插入模式3 定位到一行末尾&#xff0c;并启用插入模式4 定位到光标的…...

Tailwind CSS 实战:动画效果设计与实现

在现代网页设计中,动画效果就像是一位优秀的舞者,通过流畅的动作为用户带来愉悦的视觉体验。记得在一个产品展示网站项目中,我们通过添加精心设计的动画效果,让用户的平均停留时间提升了 35%。今天,我想和大家分享如何使用 Tailwind CSS 打造优雅的动画效果。 设计理念 设计动…...

【动手学电机驱动】STM32-MBD(3)Simulink 状态机模型的部署

STM32-MBD&#xff08;1&#xff09;安装 Simulink STM32 硬件支持包 STM32-MBD&#xff08;2&#xff09;Simulink 模型部署入门 STM32-MBD&#xff08;3&#xff09;Simulink 状态机模型的部署 【动手学电机驱动】STM32-MBD&#xff08;3&#xff09;Simulink 状态机模型部署…...

Linux 服务器启用 DNS 加密

DNS 加密的常用协议包括 DNS over HTTPS (DoH)、DNS over TLS (DoT) 和 DNSCrypt。以下是实现这些加密的步骤和工具建议&#xff1a; 1. 使用 DoH (DNS over HTTPS) 工具推荐&#xff1a; cloudflared&#xff08;Cloudflare 提供的客户端&#xff09;doh-client&#xff08;…...

PyTorch不同优化器比较

常见优化器介绍 - SGD&#xff08;随机梯度下降&#xff09;&#xff1a;是最基本的优化器之一&#xff0c;通过在每次迭代中沿着损失函数的负梯度方向更新模型参数。在大规模数据集上计算效率高&#xff0c;对于凸问题和简单模型效果较好。但收敛速度慢&#xff0c;容易陷入局…...

stm32的掉电检测机制——PVD

有时在一些应用中&#xff0c;我们需要检测系统是否掉电了&#xff0c;或者要在掉电的瞬间需要做一些处理。 STM32内部自带PVD功能&#xff0c;用于对MCU供电电压VDD进行监控。 STM32就有这样的掉电检测机制——PVD(Programmable Voltage Detecter)&#xff0c;即可编程电压检…...

Nginx 文件名逻辑漏洞(CVE-2013-4547)

目录 漏洞原理 影响版本 漏洞复现 漏洞原理 CGI&#xff1a;是一种协议&#xff0c;定义了web服务器传递的数据格式。 FastCGI&#xff1a;优化版的CGI程序 PHP-CGI&#xff1a;PHP解释器&#xff0c;能够对PHP文件进行解析并返回相应的解析结果 PHP-FPM&#xff1a;Fas…...

Java 21 优雅和安全地处理 null

在 Java 21 中,判断 null 依然是开发中常见的需求。通过使用现代 Java 提供的工具和特性,可以更加优雅和安全地处理 null。 1. 使用 Objects.requireNonNull Objects.requireNonNull 是标准的工具方法,用于快速判断并抛出异常。 示例 import java.util.Objects;public c…...

AWS Glue基础知识

AWS Glue 是一项完全托管的 ETL&#xff08;提取、转换、加载&#xff09;服务&#xff0c;与考试相关&#xff0c;尤其是在数据集成、处理和分析方面。 1.数据集成和 ETL&#xff08;提取、转换、加载&#xff09; AWS Glue 主要用于构建 ETL 管道以准备数据以进行分析。作为…...

Kubernetes——part4-1 Kubernetes集群 服务暴露 Nginx Ingress Controller

Kubernetes集群 服务暴露 Nginx Ingress Controller 一、ingress控制器 1.1 ingress控制器作用 &#xff08;类似于slb&#xff0c;做代理服务&#xff09; ingress controller可以为kubernetes 集群外用户访问Kubernetes集群内部pod提供代理服务。 提供全局访问代理访问流程…...

Flutter入门,Flutter基础知识总结。

Flutter是Google推出的一种移动应用开发框架&#xff0c;它允许开发者使用一套代码库同时开发Android和iOS应用。以下是对Flutter知识点的详细总结&#xff1a; 一、Flutter概述 特点&#xff1a;跨平台、高保真、高性能。 编程语言&#xff1a;使用Dart语言编写。 设计理念&…...

weight decay 和L2是一个东西吗

weight decay和L2正则化本质上是相同的概念。 weight decay&#xff08;权重衰减&#xff09;和L2正则化在深度学习中都是用来防止模型过拟合的常用技术。它们通过对损失函数添加一个正则项来限制模型参数的大小&#xff0c;从而控制模型的复杂度。具体来说&#xff0c;L2正则…...

JavaScript系列(8)-- Array高级操作

JavaScript Array高级操作 &#x1f4da; 在前七篇文章中&#xff0c;我们探讨了JavaScript的语言特性、ECMAScript标准、引擎工作原理、数值类型、字符串处理、Symbol类型和Object高级特性。今天&#xff0c;让我们深入了解JavaScript中的Array高级操作。数组是最常用的数据结…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...