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

【C++进阶】三、二叉搜索树

目录

一、二叉搜索树

1.1 概念

1.2 二叉搜索树操作

二、二叉搜索树实现

2.1 框架总览

2.2 实现接口总览

2.2.1 构造函数

2.2.2 拷贝构造

2.2.3 赋值重载

2.2.4 析构函数

2.2.5 二叉搜索树的遍历

2.2.6 插入函数

2.2.7 查找函数

2.2.8 删除函数

 2.3 二叉搜索数完整代码

三、二叉搜索树的应用

3.1 K模型

3.2 KV模型

四、二叉搜索树的性能分析


前言:二叉搜索树是数据结构初阶二叉树的一部分,二叉搜索树为后序所学的 map 和 set 做准备

一、二叉搜索树

1.1 概念

        二叉搜索树(BST,Binary Search Tree)又称二叉排序树,它或者是一棵空树,二叉树搜索树具有以下性质:

  1. 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  2. 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  3. 它的左右子树也分别为二叉搜索树

比如,下面就是一颗二叉搜索树 

左子树小于根节点,右子树大于根节点,每颗子树都保持这样的特性,这样的树就称为二叉搜索树

        二叉搜索树进行中序遍历,遍历出来的结果是有序的(升序),二叉搜索树一般都是去重的,即没有相同的值

1.2 二叉搜索树操作

二叉搜索树的主要接口就是插入、查找、删除、遍历

(1)查找(Find)

  1. 从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找
  2. 最多查找高度次,走到到空,还没找到,这个值不存在

(2)插入(Insert)

插入一个节点,插入后保持二叉搜索树的性质,二叉搜索树实现下面解释

(3)删除(Erase)

删除一个节点,删除后保持二叉搜索树的性质,二叉搜索树实现下面解释

(4)遍历(InOrder)

使用中序遍历即可,遍历结果为升序序列

二、二叉搜索树实现

2.1 框架总览

        要实现二叉搜索树,我们首先需要实现一个节点类,结点类当中包含三个成员变量:结点的值、左指针、右指针,结点类当中只需实现一个构造函数即可

 二叉搜索树类(BSTree)里面的成员变量只要包含一个根节点 _root 即可

为了书写简单,对 BSTreeNode<K> 进行 typedef 为 Node

typedef BSTreeNode<K> Node

template<class K>
struct BSTreeNode
{BSTreeNode(const K& key):_key(key), _left(nullptr), _right(nullptr){}K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;
};template<class K>
class BSTree
{typedef BSTreeNode<K> Node;
public:private:Node* _root;
};

2.2 实现接口总览

template<class K>
struct BSTreeNode
{BSTreeNode(const K& key):_key(key), _left(nullptr), _right(nullptr){}K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;
};template<class K>
class BSTree
{typedef BSTreeNode<K> Node;
public://构造函数BSTree(){}//拷贝构造BSTree(const BSTree<K>& t){}//赋值重载BSTree<K>& operator=(BSTree<K> t){}//析构~BSTree(){}bool Insert(const K& key){}bool Find(const K& key){}bool Erase(const K& key){}//遍历搜索树void InOrder(){}private:Node* _root;
};

2.2.1 构造函数

构造函数非常简单,构造一个空树即可

//构造函数BSTree():_root(nullptr){}

2.2.2 拷贝构造

由于要进行递归操作,就不能把递归操作写在拷贝构造函数里面,需要另写一个函数,这个函数设置为私有,拷贝构造也是深拷贝

//拷贝构造
BSTree(const BSTree<K>& t)
{_root = Copy(t._root);
}private:Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* newRoot = new Node(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;}

2.2.3 赋值重载

赋值重载直接使用现代写法,复用拷贝构造,不解释了,赋值重载也是深拷贝

//赋值重载
BSTree<K>& operator=(BSTree<K> t)
{swap(_root, t._root);return *this;
}

2.2.4 析构函数

析构函数也是如此,需要进行递归操作,需要另写一个函数进行递归操作

//析构
~BSTree()
{Destroy(_root);_root = nullptr;
}private:void Destroy(Node* root){if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;}

2.2.5 二叉搜索树的遍历

遍历使用中序遍历即可,遍历出来的结果是升序的,因为无法使用类成员变量,就无法传根进行递归遍历,所以也需要另写一个函数

代码如下: 

//遍历搜索树
void InOrder()
{_InOrder(_root);cout << endl;
}private:void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}

2.2.6 插入函数

根据二叉搜索树的性质,其插入操作非常简单:

  1. 如果是空树,则直接将插入结点作为二叉搜索树的根结点
  2. 如果不是空树,则按照二叉搜索树的性质进行结点的插入

若不是空树,插入结点的具体操作如下:

  • 若待插入结点的值小于根结点的值,则需要将结点插入到左子树当中
  • 若待插入结点的值大于根结点的值,则需要将结点插入到右子树当中
  • 若待插入结点的值等于根结点的值,则插入结点失败(二叉搜索树)

插入成功返回 true,插入失败返回 false 

代码如下: 

bool Insert(const K& key){//_root为空树if (_root == nullptr){_root = new Node(key);return true;}//不为空树,进行查找Node* parent = nullptr;Node* cur = _root;while (cur)//遇到空就结束{if (_root->_key > key)//在左子树{parent = cur;cur = cur->_left;}else if (_root->_key < key)//在右子树{parent = cur;cur = cur->_right;}else//相等,直接返回,不允许插入相同值{return false;}}cur = new Node(key);if (parent->_key > key)//parent节点的_key比key大,插入到左边{parent->_left = cur;}else//parent节点的_key比key小,插入到右边{parent->_right = cur;}return true;}

2.2.7 查找函数

根据二叉搜索树的特性,,分以下几种情况:

  1. 若树为空树,则查找失败,返回 false
  2. 若key值小于当前结点的值,则应该在该结点的左子树当中进行查找
  3. 若key值大于当前结点的值,则应该在该结点的右子树当中进行查找
  4. 若key值等于当前结点的值,则查找成功,返回 true
  5. 查找完了,还是没有找到,返回 false

代码如下: 

    bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else//找到了{return true;}}//空树或者找不到return false;}

2.2.8 删除函数

        二叉搜索树的删除函数是最难实现的,若是在二叉树当中没有找到待删除结点,则直接返回 false 表示删除失败即可,但若是找到了待删除结点,此时就有以下三种情况:

  1. 待删除结点的左子树为空
  2. 待删除结点的右子树为空
  3. 待删除结点的左右子树均不为空

下面进行一对一处理:

(1)待删除结点的左子树为空,即右子树不为空

        若待删除结点的左子树为空,那么当我们在二叉搜索树当中找到该结点后,只需先让其父结点指向该结点的右孩子结点,然后再将该结点释放便完成了该结点的删除,进行删除操作后仍保持二叉搜索树的特性

动图演示:

 (2)待删除结点的右子树为空,即左子树不为空

        若待删除结点的右子树为空,那么当我们在二叉搜索树当中找到该结点后,只需先让其父结点指向该结点的左孩子结点,然后再将该结点释放便完成了该结点的删除,进行删除操作后仍需要保持二叉搜索树的特性

动图演示:

 (3)待删除结点的左右子树均不为空

        若待删除结点的左右子树均不为空,那么当我们在二叉搜索树当中找到该结点后,可以使用替换法进行删除

有两种替换方法:可以将让待删除结点左子树当中值最大的结点,或是待删除结点右子树当中值最小的结点代替待删除结点被删除(下面都以最小的结点代替待删除为例)

        然后将待删除结点的值改为代替其被删除的结点的值即可,而代替待删除结点被删除的结点,必然左右子树当中至少有一个为空树,因此删除该结点的方法与前面说到的情(1)(2)的方法相同

注意:只能是待删除结点左子树当中值最大的结点,或是待删除结点右子树当中值最小的结点代替待删除结点被删除,因为只有这样才能使得进行删除操作后的二叉树仍保持二叉搜索树的特性

动图演示:

代码如下:

bool Erase(const K& key)
{Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else//找到了要删除的节点{//左为空,右不为空if (cur->_left == nullptr){if (cur == _root)//要删除的为根节点{_root = cur->_right;}else//非根节点{parent->_right = cur->_right;}delete cur;}else if (cur->_right == nullptr)//左不为空,右为空{if (cur == _root)//要删除的为根节点{_root = cur->_left;}else//非根节点{parent->_left = cur->_left;}delete cur;}else//左右不为空,替换删除{//左右不为空,需要左子树的最大值 或 右子树的左小值充当新的根(对被删除节点进行值替换,然后进行删除)Node* minParent = cur;Node* minRight = cur->_right;//这里选用最小值进行替换while (minRight->_left){minParent = minRight;minRight = minRight->_left;}cur->_key = minRight->_key;//值替换,minRight换不换没影响,minRight是要被删除的//分两种情况if (minRight == minParent->_left){minParent->_left = minRight->_right;}else{minParent->_right = minRight->_right;}delete minRight;}return true;}}return false;
}

 2.3 二叉搜索数完整代码

BSTree.h

#pragma oncetemplate<class K>
struct BSTreeNode
{BSTreeNode(const K& key):_key(key), _left(nullptr), _right(nullptr){}K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;
};template<class K>
class BSTree
{typedef BSTreeNode<K> Node;
public://构造函数BSTree():_root(nullptr){}//拷贝构造BSTree(const BSTree<K>& t){_root = Copy(t._root);}//赋值重载BSTree<K>& operator=(BSTree<K> t){swap(_root, t._root);return *this;}//析构~BSTree(){Destroy(_root);_root = nullptr;}bool Insert(const K& key){//_root为空树if (_root == nullptr){_root = new Node(key);return true;}//不为空树,进行查找Node* parent = nullptr;Node* cur = _root;while (cur)//遇到空就结束{if (_root->_key > key)//在左子树{parent = cur;cur = cur->_left;}else if (_root->_key < key)//在右子树{parent = cur;cur = cur->_right;}else//相等,直接返回,不允许插入相同值{return false;}}cur = new Node(key);if (parent->_key > key)//parent节点的_key比key大,插入到左边{parent->_left = cur;}else//parent节点的_key比key小,插入到右边{parent->_right = cur;}return true;}bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else//找到了{return true;}}//空树或者找不到return false;}bool Erase(const K& key){Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else//找到了要删除的节点{//左为空,右不为空if (cur->_left == nullptr){if (cur == _root)//要删除的为根节点{_root = cur->_right;}else//非根节点{parent->_right = cur->_right;}delete cur;}else if(cur->_right == nullptr)//左不为空,右为空{if (cur == _root)//要删除的为根节点{_root = cur->_left;}else//非根节点{parent->_left = cur->_left;}delete cur;}else//左右不为空,替换删除{//左右不为空,需要左子树的最大值 或 右子树的左小值充当新的根(对被删除节点进行值替换,然后进行删除)Node* minParent = cur;Node* minRight = cur->_right;//这里选用最小值进行替换while (minRight->_left){minParent = minRight;minRight = minRight->_left;}cur->_key = minRight->_key;//值替换,minRight换不换没影响,minRight是要被删除的//分两种情况if (minRight == minParent->_left){minParent->_left = minRight->_right;}else{minParent->_right = minRight->_right;}delete minRight;}return true;}}return false;}//遍历搜索树void InOrder(){_InOrder(_root);cout << endl;}
private:void Destroy(Node* root){if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;}Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* newRoot = new Node(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}
private:Node* _root;
};

Test.cpp

#include <iostream>
using namespace std;#include "BSTree.h"void Test()
{BSTree<int> t;t.Insert(4);t.Insert(3);t.Insert(5);t.Insert(4);t.Insert(6);t.Insert(1);t.Insert(7);t.Insert(9);t.InOrder();//拷贝构造BSTree<int> t2 = t;t2.InOrder();//查找cout << t2.Find(1) << endl;cout << t2.Find(8) << endl;//赋值重载BSTree<int> t3;t3 = t;t3.InOrder();//删除t3.Erase(4);t3.InOrder();t3.Erase(5);t3.InOrder();t3.Erase(3);t3.InOrder();t3.Erase(7);t3.InOrder();
}int main()
{Test();return 0;
}

三、二叉搜索树的应用

3.1 K模型

K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值

比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:

  1. 以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
  2. 在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误 

3.2 KV模型

KV模型:每一个关键码 Key,都有与之对应的值 Value,即<Key, Value>的键值对,通过Key查找 Value

该种方式在现实生活中非常常见:
        比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文<word, chinese>就构成一种键值对;

        再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word, count>就构成一种键值对

四、二叉搜索树的性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能

        对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树

对于有n个结点的二叉搜索树:

  1. 最优的情况下,二叉搜索树为完全二叉树,其平均比较次数为:O(logN)
  2. 最差的情况下,二叉搜索树退化为单支树,其平均比较次数为:O(N / 2)

所以实际上,二叉搜索树在极端情况下是没办法保证效率的,因此由二叉搜索树又衍生出来了AVL树、红黑树,后面准备学 

----------------我是分割线---------------

文章到这里就结束了,下一篇即将更新

相关文章:

【C++进阶】三、二叉搜索树

目录 一、二叉搜索树 1.1 概念 1.2 二叉搜索树操作 二、二叉搜索树实现 2.1 框架总览 2.2 实现接口总览 2.2.1 构造函数 2.2.2 拷贝构造 2.2.3 赋值重载 2.2.4 析构函数 2.2.5 二叉搜索树的遍历 2.2.6 插入函数 2.2.7 查找函数 2.2.8 删除函数 2.3 二叉搜索数完整…...

电脑系统崩溃怎么修复教程

系统崩溃了怎么办? 如今的软件是越来越复杂、越来越庞大。由系统本身造成的崩溃即使是最简单的操作&#xff0c;比如关闭系统或者是对BIOS进行升级都可能会对PC合操作系统造成一定的影响。下面一起来看看电脑系统崩溃修复方法步骤。 工具/原料&#xff1a; 系统版本&#xf…...

语义分割数据标注案例分析

语义分割&#xff08;Semantic Segmentation&#xff09;是计算机视觉领域中的一种重要任务&#xff0c;它的目的是将图像中的每个像素分配到对应的语义类别中。简单来说&#xff0c;就是将一张图像分割成多个区域&#xff0c;并为每个像素指定一个标签&#xff0c;标识出它属于…...

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(多指标评价)

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(多指标评价) 文章目录 回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(多指标评价)预测效果基本介绍程序设计参考资料预测效果 基本介绍 GRU神经网络是LST...

驱动程序开发:Buildroot根文件系统构建并加载驱动文件xxx.ko测试

目录一、buildroot根文件系统简介二、buildroot下载三、buildroot构建根文件系统1、配置 buildroot①配置 Target options②配置 Toolchain③配置 System configuration④配置 Filesystem images⑤禁止编译 Linux 内核和 uboot2、 buildroot 下的 busybox 配置①修改 Makefile&…...

R+VIC模型融合实践技术应用及未来气候变化模型预测

目录 理论专题一&#xff1a;VIC模型的原理及特点 综合案例一&#xff1a;基于QGIS的VIC模型建模 理论专题二&#xff1a;VIC模型率定验证 综合案例二&#xff1a;基于R语言VIC参数率定和优化 理论专题三&#xff1a;遥感技术与未来气候变化 综合案例三&#xff1a;运用V…...

第六章.决策树(Decision Tree)—ID3算法,C4.5算法

第六章.决策树(Decision Tree) 6.1 ID3算法,C4.5算法 1.决策树适用的数据类型 比较适合分析离散数据&#xff0c;如果是连续数据要先转换成离散数据再做分析 2.信息熵 1).概念&#xff1a; 一条信息的信息量大小和它的不确定性有直接的关系&#xff0c;要搞清楚一件非常不确…...

springboot+pgbouncer+postgres数据库连接池集成方案及问题解决

期望通过每一次分享&#xff0c;让技术的门槛变低&#xff0c;落地更容易。 —— around 前言 旨在解决微服务项目全是连接池并影响数据库并发连接&#xff0c;作者的环境是基于sprongboot微服务连接postgres数据库&#xff0c;每个微服务的DAO层配置都使用了连接池技术。后续…...

Mysql 常用日期处理函数

Mysql 常用日期处理函数 1 建表语句 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0; -- ---------------------------- -- Table structure for emp -- ---------------------------- DROP TABLE IF EXISTS emp; CREATE TABLE emp (EMPNO int(4) NOT NULL,ENAME varchar(10…...

Pod中容器的健康检查

健康检查 上篇文章中我们了解了Pod中容器的生命周期的两个钩子函数&#xff0c;PostStart与PreStop&#xff0c;其中PostStart是在容器创建后立即执行的&#xff0c;而PreStop这个钩子函数则是在容器终止之前执行的。除了上面这两个钩子函数以外&#xff0c;还有一项配置会影响…...

信贷系统学习总结(5)—— 简单的风控示例(含代码)

一、背景1.为什么要做风控?目前我们业务有使用到非常多的AI能力,如ocr识别、语音测评等,这些能力往往都比较费钱或者费资源,所以在产品层面也希望我们对用户的能力使用次数做一定的限制,因此风控是必须的!2.为什么要自己写风控?那么多开源的风控组件,为什么还要写呢?是不是想…...

Java知识复习(四)多线程、并发编程

1、进程、线程和程序 进程&#xff1a;进程是程序的一次执行过程&#xff0c;是系统运行程序的基本单位&#xff0c;因此进程是动态的&#xff1b;在 Java 中&#xff0c;当我们启动 main 函数时其实就是启动了一个 JVM 的进程&#xff0c;而 main 函数所在的线程就是这个进程…...

一个9个月测试经验的人,居然在面试时跟我要18K,我都被他吓到了····

2月初我入职了深圳某家创业公司&#xff0c;刚入职还是很兴奋的&#xff0c;到公司一看我傻了&#xff0c;公司除了我一个测试&#xff0c;公司的开发人员就只有3个前端2个后端还有2个UI&#xff0c;在粗略了解公司的业务后才发现是一个从零开始的项目&#xff0c;目前啥都没有…...

zigbee与WIFI同频干扰问题

zigbee与WIFI同频干扰 为了降低Wifi信道与Zigbee信道的同频干扰问题&#xff0c;Zigbee联盟在《Zigbee Home Automation Public Application Profile》中推荐使用11,14,15,19,20,24,25这七个信道。 为什么呢&#xff0c;我们看一下Wifi和Zigbee的信道分布。 WiFi带宽对干扰的…...

git拉取指定的单个或多个文件或文件夹

直接上步骤 初始化仓库 git init拉取远程仓库信息&#xff0c;省略号为仓库地址 git remote add -f origin http://****.git开启 sparse clone git config core.sparsecheckout true配置需要拉取的文件夹 有一个指定一个&#xff0c;有多个指定多个&#xff0c;路径写对即可&a…...

不是,到底有多少种图片懒加载方式?

一、也是我最开始了解到的 js方法&#xff0c;利用滚动事件&#xff0c;判断当时的图片位置是否在可视框内&#xff0c;然后进行渲染。 弊端&#xff1a;代码冗杂&#xff0c;你还要去监听页面的滚动事件&#xff0c;这本身就是一个不建议监听的事件&#xff0c;即便是我们做了…...

CAD坐标有哪些输入方式?来看看这些CAD坐标输入方式!

在CAD设计过程中&#xff0c;有时需要通过已知坐标点来画图&#xff0c;有时又需要通过已知角度和距离来画图&#xff0c;在这种情况下&#xff0c;由于已知条件不同&#xff0c;所以便需要用不同的方式来定位点。那么&#xff0c;你知道CAD坐标有哪些输入方式吗&#xff1f;本…...

铰链、弹簧,特殊的物理关节

title: 铰链、弹簧&#xff0c;特殊的物理关节 date: 2023-02-28T13:32:57Z lastmod: 2023-02-28T14:24:06Z 铰链关节&#xff08;Hinge Join&#xff09;组件 组件-Physics-Hinge Join Anchor 当物体挂载铰链组件以后&#xff0c;组件下Anchor等同于边长为1的立方体。当这…...

Android Studio相关记录

目录Android Studio 便捷插件Android LogcatJava文件的类头模板Android Studio 使用遇到的问题解决方案org.jetbrains.annotations.NullableBuild 控制台编译输出中文乱码Terminal 使用 git 命令窗口git 命令窗口中文乱码Android Studio 便捷插件 Android Logcat 配置路径 Fi…...

Linux 基础介绍-基础命令

文章目录01 学习目标02 Linux/Unix 操作系统简介2.1 Linux 操作系统的目标2.2 Linux 操作系统的作用2.3 Unix 家族历史2.4 Linux 家族历史2.5 Linux 和Unix 的联系2.6 Linux 内核介绍2.7 Linux 发行版本2.8 Unix/Linux 开发应用领域介绍03 Linux 目录结构3.1 Win 和Linux 文件系…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...