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

数据结构--二叉搜索树的实现

目录

1.二叉搜索树的概念

2.二叉搜索树的操作

二叉搜索树的插入

中序遍历(常用于排序)

二叉搜索树的查找

二叉搜索树的删除

完整二叉树代码:

二叉搜索树的应用

key/value搜索模型整体代码


1.二叉搜索树的概念

二叉搜索树又称二叉排序树,它或者是一棵空树 ,或者是具有以下性质的二叉树 :
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别 为二叉搜索树
注:搜索二叉树中没有重复值
二叉搜索树与其结点的代码实现
#include<iostream>
using namespace std;template<class K>//搜索二叉树的结点
struct BSTreeNode
{K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;BSTreeNode(const K& s = K()):_key(s), _left(nullptr), _right(nullptr){}
};template<class K>//搜索二叉树
class BSTree
{
public:BSTree():_root(nullptr){}//...各种操作二叉搜索树方法的实现//...
private:typedef BSTreeNode<K> Node;Node* _root;
};

2.二叉搜索树的操作

二叉搜索树的插入

这里根据二叉搜索树的概念分两种情况:

a. 树为空,则直接新增节点,赋值给 root 指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

非递归

bool Insert(const K & key){if (_root == nullptr)//情况a{_root = new Node(key);}else//情况b{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  //数字重复插入失败{return false;}}cur = new Node(key);if (parent->_key > key)//判断插入结点是在parent的左子树还是右子树{parent->_left = cur;}else{parent->_right = cur;}return true;}}

为什么要定义parent变量记录cur的父节点?

这里我们要知道,cur=new Node(key)这行代码的真正意义是给cur赋值,并没有把结点插入到树中。

注:在向二叉搜索树插入时,一定要判断是在父节点的左子树还是右子树。

递归:

public: 
bool InsertR(const K& key)
{return _insertR(_root, key);
}private:
bool _insertR(Node*& root, const K& key)
{if (root == nullptr){root = new Node(key);return true;}else{if (root->_key > key){return _insertR(root->_left, key);}else if (root->_key < key){return _insertR(root->_right, key);}else{return false;}}
}

注:由于使用递归时,需要用到成员变量_root作为实参,但是在类外面无法直接调用,因此,将递归调用的函数封装到了InsertR()里面。

为什么这里不用记录父节点,就可以插入到树中。

这里我们要注意函数的第一个变量,我们使用了引用!

这里的root就是父节点的左孩子或有孩子。

那么在非递归里面可以使用引用来达到不设置parent变量来记录父节点吗?
不能,因为在C++里引用只能指向一个。之后就不能改变指向。在递归中,我们是在传参是使用的,每次引用都重新开辟了一个新的变量,而非递归中我们一直用的是一个变量。

中序遍历(常用于排序)

public:
void Inorder()
{_Inorder(_root);
}private:
void _Inorder(Node* root)
{if (root == nullptr)return;_Inorder(root->_left);cout << root->_key << "  ";_Inorder(root->_right);
}

这里根据二叉搜索树的概念我们清楚,其中序遍历相当于将树里面的数据按从小到大排序输出。

二叉搜索树的查找

查找方法:

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

注意:

为完全二叉树时间复杂度最好,为O(log n)   

树的结点全部为左孩子或右孩子时,时间复杂度最坏,为O(n)

非递归

bool Find(const K& key)
{if (_root == nullptr)//树为空return false;Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->left;// _key>key.左走}else if (cur->_key < key){cur = cur->_right;//_key<key.右走}else{return true;//相等,找到}}return false;//没有一个相等
}

递归:

public:
Node* FindR(const K& key)
{return _FindR(_root, key);
}private:
Node* _FindR(Node* root, const K& key)
{if (root == nullptr)return nullptr;if (root->_key > key){_FindR(root->_left, key);}else if (root->_key < key){_FindR(root->_right, key);}else{return root;}
}

二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回 , 否则要删除的结点可能分下面四种情
况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点
看起来有待删除节点有 4 中情况,实际情况 a 可以与情况 b 或者 c 合并起来,因此真正的删除过程
如下:
情况 b :删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点 -- 直接删除
情况 c :删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点 -- 直接删除
情况 d :在它的右子树中寻找中序下的第一个结点 ( 关键码最小 ) ,用它的值填补到被删除节点
中,再来处理该结点的删除问题 -- 替换法删除
bool Erase(const K& key)
{if (_root == nullptr)return false;Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = nullptr;cur = cur->_right;}else{if (cur->_left == nullptr)//情况a{if (cur == _root)//特殊条件,等于根节点{_root = cur->_right;}else{if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete cur;}else if (cur->right == nullptr)//情况b{if (cur == _root) //特殊条件,等于根节点{_root = cur->_left;}else{if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete cur;}else            //情况c{Node* parent = cur;Node* subnode = cur->_right;while (subnode->_left){parent = subnode;subnode = subnode->_left;}swap(cur->_key, subnode->_key);if (parent->_right == subnode)   //当cur->_right->left==nullptr{parent->_right = subnode->_right;}else{parent->_left = subnode->_right;}delete subnode;}return true;}}return false;
}

递归:

public:bool EraseR(const K& key)
{_EraseR(_root,key);
}private:bool _EraseR(Node*& root, const K& key)
{if (root == nullptr){return false;}if (root->_key > key){return _EraseR(root->_left, key);}else if (root->_key < key){return _EraseR(root->_right, key);}else{if (root->_left == nullptr){Node* temp = root;root = root->_right;delete temp;}else if (root->right){Node* temp = root;root = root->_left;delete temp;}else{Node* subnode = root->_right;while (subnode->left){subnode = subnode->_left;}swap(root->_key, subnode->_key);return _EraseR(root - right, key);}}
}

完整二叉树代码:

#include<iostream>
using namespace std;template<class K>//搜索二叉树的结点
struct BSTreeNode
{K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;BSTreeNode(const K& s = K()):_key(s), _left(nullptr), _right(nullptr){}
};template<class K>//搜索二叉树
class BSTree
{
public:BSTree():_root(nullptr){}bool Insert(const K & key){if (_root == nullptr)//情况a{_root = new Node(key);}else//情况b{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  //数字重复插入失败{return false;}}cur = new Node(key);if (parent->_key > key)//判断插入结点是在parent的左子树还是右子树{parent->_left = cur;}else{parent->_right = cur;}return true;}}bool Find(const K& key){if (_root == nullptr)//树为空return false;Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->left;// _key>key.左走}else if (cur->_key < key){cur = cur->_right;//_key<key.右走}else{return true;//相等,找到}}return false;//没有一个相等}Node* FindR(const K& key){return _FindR(_root, key);}void Inorder(){_Inorder(_root);}bool InsertR(const K& key){return _insertR(_root, key);cout << endl;}bool Erase(const K& key){if (_root == nullptr)return false;Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if(cur->_key<key){parent = nullptr;cur = cur->_right;}else{if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete cur;}else if(cur->right==nullptr){if (cur == _root){_root = cur->_left;}else{if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete cur;}else{Node* parent = cur;Node* subnode = cur->_right;while (subnode->_left){parent = subnode;subnode = subnode->_left;}swap(cur->_key, subnode->_key);if (parent->_right == subnode){parent->_right = subnode->_right;}else{parent->_left = subnode->_right;}delete subnode;}return true;}}return false;}bool EraseR(const K& key){return _EraseR(_root, key);}private:typedef BSTreeNode<K> Node;Node* _root;bool _insertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}else{if (root->_key > key){return _insertR(root->_left, key);}else if (root->_key < key){return _insertR(root->_right, key);}else{return false;}}}void _Inorder(Node* root){if (root == nullptr)return;_Inorder(root->_left);cout << root->_key<<"  ";_Inorder(root->_right);}Node*_FindR(Node* root, const K& key){if (root == nullptr)return nullptr;if (root->_key > key){_FindR(root->_left, key);}else if (root->_key < key){_FindR(root->_right, key);}else{return root;}}bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key > key){return _EraseR(root->_left, key);}else if (root->_key < key){return _EraseR(root->_right, key);}else{if (root->_left == nullptr){Node* temp = root;root = root->_right;delete temp;}else if (root->right){Node* temp = root;root = root->_left;delete temp;}else{Node* subnode = root->_right;while (subnode->left){subnode = subnode->_left;}swap(root->_key, subnode->_key);return _EraseR(root - right, key);}}}
};
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

二叉搜索树的应用

1. K 模型: K 模型即只有 key 作为关键码,结构中只需要存储 Key 即可,关键码即为需要搜索到
的值
比如: 给一个单词 word ,判断该单词是否拼写正确 ,具体方式如下:
以词库中所有单词集合中的每个单词作为 key ,构建一棵二叉搜索树
在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。
2. KV 模型:每一个关键码 key ,都有与之对应的值 Value ,即 <Key, Value> 的键值对 。该方式在现实生活中非常常见:
比如 英汉词典就是英文与中文的对应关系 ,通过英文可以快速找到与其对应的中文,英
文单词与其对应的中文 <word, chinese> 就构成一种键值对;
再比如 统计单词次数 ,统计成功后,给定单词就可快速找到其出现的次数, 单词与其出
现次数就是 <word, count> 就构成一种键值对

key/value搜索模型整体代码

#pragma once
// 改造二叉搜索树为KV结构
template<class K, class V>
struct BSTNode
{BSTNode(const K& key = K(), const V& value = V()): _pLeft(nullptr), _pRight(nullptr), _key(key), _Value(value){}BSTNode<T>* _pLeft;BSTNode<T>* _pRight;K _key;V _value
};template<class K, class V>
class BSTree
{typedef BSTNode<K, V> Node;
public:bool Insert(const K& key,const V& value){if (_root == nullptr)//情况a{_root = new Node(key,value);}else//情况b{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  //数字重复插入失败{return false;}}cur = new Node(key,value);if (parent->_key > key)//判断插入结点是在parent的左子树还是右子树{parent->_left = cur;}else{parent->_right = cur;}return true;}}bool Find(const K& key){if (_root == nullptr)//树为空return false;Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->left;// _key>key.左走}else if (cur->_key < key){cur = cur->_right;//_key<key.右走}else{return true;//相等,找到}}return false;//没有一个相等}bool Erase(const K& key){if (_root == nullptr)return false;Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = nullptr;cur = cur->_right;}else{if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete cur;}else if (cur->right == nullptr){if (cur == _root){_root = cur->_left;}else{if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete cur;}else{Node* parent = cur;Node* subnode = cur->_right;while (subnode->_left){parent = subnode;subnode = subnode->_left;}swap(cur->_key, subnode->_key);if (parent->_right == subnode){parent->_right = subnode->_right;}else{parent->_left = subnode->_right;}delete subnode;}return true;}}return false;}void Inorder(){_Inorder(_root);}private:Node* _root;void _Inorder(Node* root){if (root == nullptr)return;_Inorder(root->_left);cout << root->_key << ":"<<root->_value<<endl;_Inorder(root->_right);}
};
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

相关文章:

数据结构--二叉搜索树的实现

目录 1.二叉搜索树的概念 2.二叉搜索树的操作 二叉搜索树的插入 中序遍历(常用于排序) 二叉搜索树的查找 二叉搜索树的删除 完整二叉树代码&#xff1a; 二叉搜索树的应用 key/value搜索模型整体代码 1.二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一…...

《微信小程序开发从入门到实战》学习六十八

6.6 网络API 6.6.1 网络API 使用wx.request接口可以发起网络请求。该接口接受一个Object参&#xff0c;参数支持属性如下所示&#xff1a; url(必填)&#xff1a;开发者服务器地址 data&#xff1a;请求的参数&#xff0c;类型为string/object/ArrayBuffer header&#xf…...

阿里是如何去“O”的?

大家好&#xff0c;我是老猫&#xff0c;猫头鹰的“猫”。 今天我们来聊聊数据库这个话题。 2009年&#xff0c;阿里提出“去IOE化”的概念&#xff0c;这在当时看起来是天方夜谭&#xff0c;但目前来看可以说是"轻舟已过万重山"。 IOE是传统IT三大件&#xff0c;…...

蓝桥杯备赛 day 1 —— 递归 、递归、枚举算法(C/C++,零基础,配图)

目录 &#x1f308;前言 &#x1f4c1; 枚举的概念 &#x1f4c1;递归的概念 例题&#xff1a; 1. 递归实现指数型枚举 2. 递归实现排列型枚举 3. 递归实现组合型枚举 &#x1f4c1; 递推的概念 例题&#xff1a; 斐波那契数列 &#x1f4c1;习题 1. 带分数 2. 反硬币 3. 费解的…...

87 双指针解验证回文字符串II

问题描述&#xff1a;简单给定一个非空字符串s&#xff0c;最多删除一个字符&#xff0c;判断是否成为回文字符串。 双指针解法&#xff1a;指针1指向开头&#xff0c;指针2指向结尾&#xff0c;定义一个count记录不满足回文串的数量&#xff0c;若超过1&#xff0c;则返回fal…...

【排序算法】【二叉树】【滑动窗口】LeetCode220: 存在重复元素 III

作者推荐 【二叉树】【单调双向队列】LeetCode239:滑动窗口最大值 本文涉及的基础知识点 C算法&#xff1a;滑动窗口总结 题目 给你一个整数数组 nums 和两个整数 indexDiff 和 valueDiff 。 找出满足下述条件的下标对 (i, j)&#xff1a; i ! j, abs(i - j) < indexDi…...

OS 7--DNS配置+Apache发布网站

环境准备 centOS 7 1.配置DNS 1.1 域名为lianxi.com 1.2 为WWW服务器、FTP服务器、NEWS服务器做域名解析 1)安装DNS yum -y install bind bind-utils (如果安装不上&#xff0c;就把磁盘在重洗挂载一下&#xff09; 2&#xff09;修改DNS配置文件 vim /etc/resolv.conf…...

1月2日代码随想录二叉树的最小深度及层序遍历总结

个人认为这么一个层序遍历的章节放这么多基本一样的题目算是很没意思的了 填充每个节点的下一个右侧节点和二叉树最大深度和前面的代码几乎完全一样&#xff0c;所以我就跳过了 代码随想录 (programmercarl.com) 代码随想录 (programmercarl.com) 111.二叉树的最小深度 给…...

RK3568平台开发系列讲解(Linux系统篇)PWM系统编程

🚀返回专栏总目录 文章目录 一、什么是PWM二、PWM相关节点三、PWM应用编程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 PWM 的系统编程。 一、什么是PWM PWM,即脉冲宽度调制(Pulse Width Modulation)...

Linux CPU 数据 Metrics 指标解读

过去从未仔细了解过使用 top 和 htop 等命令时显式的CPU信息&#xff0c;本文我们详解解读和标注一下各个数据项的含义&#xff0c;同时和 Ganglia 显式的数据做一个映射。开始前介绍一个小知识&#xff0c;很多查看CPU的命令行工具都是 cat /proc/stat 里的数据&#xff0c;所…...

Ansible自动化运维(一)简介及部署、清单

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…...

深度学习MLP_实战演练使用感知机用于感情识别_keras

目录 &#xff08;1&#xff09;why deep learning is game changing?&#xff08;2&#xff09;it all started with a neuron&#xff08;3&#xff09;Perceptron&#xff08;4&#xff09;Perceptron for Binary Classification&#xff08;5&#xff09;put it all toget…...

[ffmpeg系列 02] 音视频基本知识

一 视频 RGB&#xff1a; AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB… Y&#xff1a;明亮度, Luminance或luma, 灰阶图&#xff0c; UV&#xff1a;色度&#xff0c;Chrominance或Chroma。 YCbCr: Cb蓝色分量&#xff0c;Cr是红色分量。 取值范围&#xff…...

【ASP.NET Core 基础知识】--目录

介绍 1.1 什么是ASP.NET Core1.2 ASP.NET Core的优势1.3 ASP.NET Core的版本历史 环境设置 2.1 安装和配置.NET Core SDK2.2 使用IDE&#xff08;Integrated Development Environment&#xff09;&#xff1a;Visual Studio Code / Visual Studio 项目结构 3.1 ASP.NET Core项…...

java数据结构与算法刷题-----LeetCode509. 斐波那契数

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难&#xff0c;但它就是固定套路而已。其实动态规划只…...

vue3 element plus el-table封装(二)

上文是对el-table的基本封装&#xff0c;只能满足最简单的应用&#xff0c;本文主要是在上文的基础上增加slot插槽&#xff0c;并且对col插槽进行拓展&#xff0c;增加通用性 // BaseTable.vue <template><el-table><template v-for"name in tableSlots&…...

cnn lstm结合网络

目录 特征处理例子&#xff1a; cnn 5张图片一组&#xff0c;提取特征后&#xff0c;再给lstm&#xff0c;进时间序列分类。 特征处理例子&#xff1a; import torch# 假设 tensor 是形状为 15x64 的张量 tensor torch.arange(15 * 2).reshape(15, 2) # 生成顺序编号的张量&…...

Ubuntu连接xshell

安装ssh服务器 sudo apt-get install openssh-server​ 重启ssh sudo service ssh restart 3.启动ssh服务 /etc/init.d/ssh start4.修改文件&#xff0c;允许远程登陆 sudo vi /etc/ssh/sshd_config PermitRootLogin prohibit-password #默认为禁止登录 PermitRootLogin y…...

nginx安装和配置

目录 1.安装 2.配置 3.最小配置说明 4. nginx 默认访问路径 1.安装 使用 epel 源安装 先安装 yum 的扩展包 yum install epel-release -y 再安装 nginx yum install nginx -y 在启动nginx 前先关闭防火墙 systemctl stop firewalld 取消防火墙开机自启 systemctl di…...

【头歌实训】kafka-入门篇

文章目录 第1关&#xff1a;kafka - 初体验任务描述相关知识Kafka 简述Kafka 应用场景Kafka 架构组件kafka 常用命令 编程要求测试说明答案代码 第2关&#xff1a;生产者 &#xff08;Producer &#xff09; - 简单模式任务描述相关知识Producer 简单模式Producer 的开发步骤Ka…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

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

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

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...