c++进阶之------红黑树
一、概念
红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学的许多领域中都有广泛应用,比如Java中的TreeMap和C++中的set/map等数据结构的底层实现。红黑树通过在每个节点上增加一个颜色属性(红色或黑色),并遵循一定的规则来确保树的平衡性,从而保证了各项操作的时间复杂度为O(log n)。
二、性质
红黑树具有以下性质:
-
每个节点是红色或黑色。
-
根节点是黑色。
-
所有叶子节点(NIL节点)是黑色。
-
如果一个节点是红色,则它的两个子节点都是黑色。(注:这条规则保证了从任一节点到其每个叶子节点的所有路径上不会出现两个连续的红色节点)
-
从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
三、构建红黑树
3.1 树的基本结构
#pragma once// 枚举值表示颜色
enum color
{RED,BLACK
};
// 这里我们默认按key/value结构实现
template<class K,class V>
struct RBTreeNode
{// 这里更新控制平衡也要加入parent指针pair<k, v> _kv;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;color _col;RBTreeNode(const pair<K, V>& kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr){}
};
template<class K,class V>
class RBTree
{typedef RBTreeNode<K, V> Node;
public:
private:Node* _root = nullptr;
};
3.2 树的插入
在红黑树中插入一个节点后,可能会破坏红黑树的性质,因此需要通过旋转和重新着色来恢复红黑树的平衡。插入操作的具体步骤如下:
-
插入节点:按照普通二叉查找树的插入方式插入新节点,并将新节点着色为红色。
-
检查平衡性:检查插入新节点后是否破坏了红黑树的性质。如果插入的新节点是根节点,则直接将其着色为黑色;如果新节点的父节点是黑色,则红黑树的性质未被破坏,插入结束;如果新节点的父节点是红色,则需要进行修复。
-
修复红黑树性质:根据新节点的父节点和叔叔节点的颜色以及它们的位置关系,分为以下几种情况:
-
情况一:叔叔节点是红色:将父节点和叔叔节点着色为黑色,祖父节点着色为红色,然后将祖父节点作为新的当前节点,继续检查。
-
情况二:叔叔节点是黑色,且当前节点是父节点的左孩子:此时要进行旋转来解决,单纯的变色已经不能解决问题了,以爷爷结点为基准右旋之后在变色
-
情况三:叔叔节点是黑色,且当前节点是父节点的右孩子:此时要进行左右双旋转,具体参见代码
-
注:情况123均需要考虑u p 还是p u 的问题!!!
代码显示:
bool Insert(const pair<K, V>& kv)
{if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first<kv.first){//插入的数大parent = cur;cur = cur->_right;}else if(cur->_kv.first>kv.first){parent = cur;cur = cur->_left;}else{return false;}}//找到插入的位置了cur=new Node(kv);//要是插入黑节点会导致性质5不符合,所以插红的cur->_col = RED;//考虑做左孩子还是右孩子if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent; //别忘了把_parent给到parent,否则下文的parent还是空!//由于我插入的结点必须为红,而红黑树又要求不能有两个连着的红结点//所以我们要判断一下父节点的颜色while (parent && parent->_col == RED){//父节点为红色Node* grandfather = parent->_parent;if (parent == grandfather->_left) //parent为左孩子 {// g 黑// p u 红 红Node* uncle = grandfather->_right;// 叔叔存在且为红if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK; //g和u都为红,那么一起变色就o而k之grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else{// 叔叔不存在或者存在且为黑// g 黑// p u 红 黑//c 红if (cur == parent->_left){RotateR(grandfather); //单纯变色无法解决,旋转一下parent->_col = BLACK;grandfather->_col = RED;}else{// g// p u// cRotateL(parent);RotateR(grandfather);grandfather->_col = RED;cur->_col = BLACK;}break; //处理的是一个子树,这个符合了上面的也就Ok了}} else //parent为右孩子{// g 黑// u p 红 红Node* uncle = grandfather->_left;// 叔叔存在且为红,-》变色即可if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else{// 叔叔不存在或者存在且为黑// // 旋转+变色// g 黑// u p 黑 红// c 红if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{// g 黑// u p 黑 红// c 红RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}_root->_col = BLACK;return true;
}
3.3 遍历红黑树
我们还是使用中序遍历遍历红黑树,代码如下:
void InOrder(){_InOrder(_root);cout << endl;}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);}
3.4 检查红黑树
检查的方法很简单,就是通过随便跑一条路,数一下黑色节点,并将其作为参考值,之后在遍历整棵树,看看是不是每条路上的黑色节点数都是等于参考值的,换句话说,如果我们的树满足红黑树的性质,那么就o而k之,否则就不o而k之~
// 前序递归遍历bool Check(Node* root, int blacknum, const int refnum){if (root == nullptr){// 前序遍历走到空时,意味着一条路径走完了//cout << blackNum << endl;if (refnum != blacknum){cout << "存在黑色结点的数量不相等的路径" << endl;return false;}return true;}// 检查孩子不太方便,因为孩子有两个,且不一定存在,反过来检查父亲就方便多了if (root->_col == RED && root->_parent && root->_parent->_col == RED){cout << root->_kv.first << "存在连续的红色结点" << endl;return false;}if (root->_col == BLACK){blacknum++;}return Check(root->_left, blacknum, refnum) && Check(root->_right, blacknum, refnum);}bool IsBalanceTree(){if (_root == nullptr){return true;}if (_root->_col == RED){return false;}//设置一个参考值int refnum = 0;Node* cur = _root;//随便选一条路看看几个黑的while (cur){if (cur->_col == BLACK){refnum++;}cur = cur->_left;}return Check(_root, 0, refnum);}
3.5 代码测试
#include<iostream>
#include<vector>
using namespace std;#include"RBTree.h"// 测试代码
void TestRBTree1()
{RBTree<int, int> t;//常规的测试用例int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };// 特殊的带有双旋场景的测试用例//int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };for (auto e : a){t.Insert({ e, e });}t.InOrder();cout << t.IsBalanceTree() << endl;
}void TestRBTree2()
{const int N = 10000000;vector<int> v;v.reserve(N);srand(time(0));for (size_t i = 0; i < N; i++){v.push_back(rand() + i);}RBTree<int, int> t;for (size_t i = 0; i < v.size(); ++i){t.Insert(make_pair(v[i], v[i]));}cout << t.IsBalanceTree() << endl;
}int main()
{TestRBTree1();TestRBTree2();return 0;
}
3.6 代码汇总
这里只放.h文件的!
#pragma once
#include<iostream>
#include<utility>
using namespace std;
// 枚举值表示颜色
enum color
{RED,BLACK
};
// 这里我们默认按key/value结构实现
template<class K,class V>
struct RBTreeNode
{// 这里更新控制平衡也要加入parent指针pair<K, V> _kv;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;color _col;RBTreeNode(const pair<K, V>& kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr){}
};
template<class K,class V>
class RBTree
{typedef RBTreeNode<K, V> Node;
public:bool Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first<kv.first){//插入的数大parent = cur;cur = cur->_right;}else if(cur->_kv.first>kv.first){parent = cur;cur = cur->_left;}else{return false;}}//找到插入的位置了cur=new Node(kv);//要是插入黑节点会导致性质5不符合,所以插红的cur->_col = RED;//考虑做左孩子还是右孩子if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent; //别忘了把_parent给到parent,否则下文的parent还是空!//由于我插入的结点必须为红,而红黑树又要求不能有两个连着的红结点//所以我们要判断一下父节点的颜色while (parent && parent->_col == RED){//父节点为红色Node* grandfather = parent->_parent;if (parent == grandfather->_left) //parent为左孩子 {// g 黑// p u 红 红Node* uncle = grandfather->_right;// 叔叔存在且为红if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK; //g和u都为红,那么一起变色就o而k之grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else{// 叔叔不存在或者存在且为黑// g 黑// p u 红 黑//c 红if (cur == parent->_left){RotateR(grandfather); //单纯变色无法解决,旋转一下parent->_col = BLACK;grandfather->_col = RED;}else{// g// p u// cRotateL(parent);RotateR(grandfather);grandfather->_col = RED;cur->_col = BLACK;}break; //处理的是一个子树,这个符合了上面的也就Ok了}} else //parent为右孩子{// g 黑// u p 红 红Node* uncle = grandfather->_left;// 叔叔存在且为红,-》变色即可if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else{// 叔叔不存在或者存在且为黑// // 旋转+变色// g 黑// u p 黑 红// c 红if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{// g 黑// u p 黑 红// c 红RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}_root->_col = BLACK;return true;}void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;subL->_right = parent;if (subLR)subLR->_parent = parent;Node* parentParent = parent->_parent;parent->_parent = subL;//if (parentParent == nullptr)if (parent == _root){_root = subL;subL->_parent = nullptr;}else{if (parentParent->_left == parent){parentParent->_left = subL;}else{parentParent->_right = subL;}subL->_parent = parentParent;}}void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;Node* parentParent = parent->_parent;subR->_left = parent;parent->_parent = subR;if (parentParent == nullptr){_root = subR;subR->_parent = nullptr;}else{if (parent == parentParent->_left){parentParent->_left = subR;}else{parentParent->_right = subR;}subR->_parent = parentParent;}}void InOrder(){_InOrder(_root);cout << endl;}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);}// 前序递归遍历bool Check(Node* root, int blacknum, const int refnum){if (root == nullptr){// 前序遍历走到空时,意味着一条路径走完了//cout << blackNum << endl;if (refnum != blacknum){cout << "存在黑色结点的数量不相等的路径" << endl;return false;}return true;}// 检查孩子不太方便,因为孩子有两个,且不一定存在,反过来检查父亲就方便多了if (root->_col == RED && root->_parent && root->_parent->_col == RED){cout << root->_kv.first << "存在连续的红色结点" << endl;return false;}if (root->_col == BLACK){blacknum++;}return Check(root->_left, blacknum, refnum) && Check(root->_right, blacknum, refnum);}bool IsBalanceTree(){if (_root == nullptr){return true;}if (_root->_col == RED){return false;}//设置一个参考值int refnum = 0;Node* cur = _root;//随便选一条路看看几个黑的while (cur){if (cur->_col == BLACK){refnum++;}cur = cur->_left;}return Check(_root, 0, refnum);}
private:Node* _root = nullptr;
};
四、总结及应用
在红黑树中,我们省去了ALV树的平衡因子,而换用颜色来判断树的平衡,这样使得代码的逻辑变得简单明了 ,后续我们对map和set的封装(实现mymap和myset)便会用到红黑树的思想与结构!
红黑树通过其自平衡的特性,确保了在插入、删除和查找操作中的高效性,使其成为许多实际应用中不可或缺的数据结构。
相关文章:
c++进阶之------红黑树
一、概念 红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学的许多领域中都有广泛应用,比如Java中的TreeMap和C中的set/map等数据结构的底层实现。红黑树通过在每个节点上增加一个颜色属性(红色或黑色&am…...
政安晨【超级AI工作流】—— 使用Dify通过工作流对接ComfyUI实现多工作流协同
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 目录 一、准备工作 Dify跑起来 ollama局域网化配置 Dify配置并验证 启动ComfyUI 二、…...
javaweb开发以及部署
先说一个阿里云学生无门槛免费领一年2核4g服务器的方法: 阿里云服务器学生无门槛免费领一年2核4g_阿里云学生认证免费服务器-CSDN博客 Java Web开发是使用Java编程语言开发Web应用程序的过程,通常涵盖了使用Java EE(Java Enterprise Edition…...
树莓派5介绍与系统安装
简介 Raspberry Pi 5采用运行频率为2.4GHz的64位四核Arm Cortex-A76处理器,与Raspberry Pi 4相比, CPU性能提高了2至3倍。此外,它还配备了一个800MHz的VideoCore VII GPU,可以提供大幅度的图形 性能提升,通过HDMI实现…...
菜鸟之路Day25一一前端工程化(二)
菜鸟之路Day25一一前端工程化(二) 作者:blue 时间:2025.3.19 文章目录 菜鸟之路Day25一一前端工程化(二)1.概述2.Element快速入门3.综合案例一.布局二.组件三.Axios异步加载数据1. 生命周期钩子概述2. mo…...
vue如何获取 sessionStorage的值,获取token
// 使用Axios发送请求并处理下载 import axios from axios;const handleDownload () > {const params {warehouseId: selectedWarehouseId.value};const apiUrl /api/materials/wmMatCheck/export-wmMatCheckDetail;axios.get(apiUrl, {params,responseType: blob, // 接…...
图解AUTOSAR_CP_DiagnosticLogAndTrace
AUTOSAR 诊断日志和跟踪(DLT)模块详解 AUTOSAR 经典平台中的诊断和调试关键组件 目录 1. 概述2. DLT模块架构 2.1 模块位置2.2 内部组件2.3 接口定义 3. DLT操作流程 3.1 初始化流程3.2 日志和跟踪消息处理3.3 控制命令处理 4. 数据结构与配置模型 4.1 配置类4.2 消息格式4.3 …...
微调实战 - 使用 Unsloth 微调 QwQ 32B 4bit (单卡4090)
本文参考视频教程:赋范课堂 – 只需20G显存,QwQ-32B高效微调实战!4大微调工具精讲!知识灌注问答风格微调,DeepSeek R1类推理模型微调Cot数据集创建实战打造定制大模型! https://www.bilibili.com/video/BV1…...
金仓KESV8R6任务调度
基本概念 • 程序(program) 程序对象描述调度器要运行的内容。 • 调度计划(schedule) 调度计划对象指定作业何时运行以及运行多少次。调度计划可以被多个作业共享。 • 作业(job) 作业就是用户定义的…...
Maven常见问题汇总
Maven刷新,本地仓库无法更新 现象 This failure was cached in the local repository and resolution is not reattempted until the update interval of aliyunmaven has elapsed or updates are forced原因 因为上一次尝试下载,发现对应的仓库没有这个maven配置…...
颠覆者的困局:解构周鸿祎商业哲学中的“永恒战争”
引言:被误解的破坏者 在北京海淀区知春路银谷大厦的某间会议室里,周鸿祎用马克笔在白板上画出一个巨大的爆炸图案——这是2010年360与腾讯开战前夜的战术推演场景。这个充满硝烟味的瞬间,恰是《颠覆者》精神内核的完美隐喻:在中国…...
基于ChatGPT、GIS与Python机器学习的地质灾害风险评估、易发性分析、信息化建库及灾后重建高级实践
第一章、ChatGPT、DeepSeek大语言模型提示词与地质灾害基础及平台介绍【基础实践篇】 1、什么是大模型? 大模型(Large Language Model, LLM)是一种基于深度学习技术的大规模自然语言处理模型。 代表性大模型:GPT-4、BERT、T5、Ch…...
如何实现单点登录?
单点登录(Single Sign-On, SSO)是一种身份验证机制,允许用户在多个应用系统中只登录一次,就能够访问所有受保护的系统或服务,而无需重复登录。SSO通过集中式认证来简化用户的登录体验,提高安全性,并减少管理复杂性。 一、原理 SSO的核心原理是通过一个认证中心(Ident…...
01 Overview
版本pytorch 0.4,应用期的技术 学习的前提 线性代数和概率分布,高数 内容 穷举、贪心、分治算法、动态规划 花书是经典中的经典 机器学习历史 1 基于规则的 2 经典的机器学习方法 3 深度学习 深度学习竞赛识别率超过了人类 神经网络是数学和工…...
第二天 开始Unity Shader的学习之旅之熟悉顶点着色器和片元着色器
Shader初学者的学习笔记 第二天 开始Unity Shader的学习之旅之熟悉顶点着色器和片元着色器 文章目录 Shader初学者的学习笔记前言一、顶点/片元着色器的基本结构① Shader "Unity Shaders Book/Chapter 5/ Simple Shader"② SubShader③ CGPROGRAM和ENDCG④ 指明顶点…...
moveit2基础教程上手-使用xarm6演示
0、前置信息 开发环境:wsl。 ros版本:jazzy,ubuntu版本:24.04 xarm-ros2地址 1、启动Rviz,加载 Motion Planning Plugin,实现演示功能 Getting Started — MoveIt Documentation: Rolling documentation…...
头部姿态估计(Head Pose Estimation)领域,有许多开源工具和库可供选择,一些常用的工具及其特点
在头部姿态估计(Head Pose Estimation)领域,有许多开源工具和库可供选择。以下是一些常用的工具及其特点比较: 1. OpenCV 特点: OpenCV 是一个广泛使用的计算机视觉库,提供了丰富的图像处理和计算机视觉算法。虽然 O…...
Qt调用Miniconda的python方法
1、 Win 64环境下载及安装 Miniconda 首先下载Windows 版Miniconda,https://docs.conda.io/en/latest/miniconda.html或 https://repo.anaconda.com/miniconda/ 安装界面及选择如下图所示: 安装完python3.12版报错如下。 说明:python3.11版…...
【Linux 下的 bash 无法正常解析, Windows 的 CRLF 换行符问题导致的】
文章目录 报错原因:解决办法:方法一:用 dos2unix 修复方法二:手动转换换行符方法三:VSCode 或其他编辑器手动改 总结 这个错误很常见,原因是你的 wait_for_gpu.sh 脚本 文件格式不对,具体来说…...
DSP数字信号处理
数字信号处理(Digital Signal Processing,简称DSP)是一门研究如何通过数字技术对信号进行分析、修改和合成的学科。DSP在现代电子系统中无处不在,广泛应用于音频处理、视频处理、通信、雷达、医学成像等领域。 什么是数字信号处理…...
vue3 获取当前路由信息失败问题
刷新浏览器时获取当前路由信息失败:undefined import { ref, reactive, onMounted } from vue; import { useRoute } from vue-router; const route useRoute();onMounted(()>{// 打印当前路由信息console.log(当前route, route ); // 这里的打印有值console.…...
数据驱动进化:AI Agent如何重构手机交互范式?
如果说AIGC拉开了内容生成的序幕,那么AI Agent则标志着AI从“工具”向“助手”的跨越式进化。它不再是简单的问答机器,而是一个能够感知环境、规划任务并自主执行的智能体,更像是虚拟世界中的“全能员工”。 正如行业所热议的:“大…...
汽车芯片成本控制:挑战、策略与未来趋势
一、引言 随着汽车行业的快速发展,汽车芯片在车辆中的应用越来越广泛。从简单的发动机控制单元到复杂的自动驾驶系统,芯片已成为汽车智能化、电动化的核心部件。然而,汽车芯片的高成本一直是制约汽车行业发展的重要因素之一。本文将深入探讨…...
RIP实验
RIP实验 一、实验背景 RIP协议: RIP协议(Routing Information Protocol,路由信息协议)是一种基于距离矢量的内部网关协议,即根据跳数来度量路由开销,进行路由选择。相比于其它路由协议(如OSPF、…...
NAT 实验:多私网环境下 NAPT、Easy IP 配置及 FTP 服务公网映射
NAT基本概念 定义:网络地址转换(Network Address Translation,NAT)是一种将私有(保留)地址转化为合法公网 IP 地址的转换技术,它被广泛应用于各种类型 Internet 接入方式和各种类型的网络中。作…...
电力和冷却管理:如何让数据中心“高效降温”同时节能增效
电力和冷却管理:如何让数据中心“高效降温”同时节能增效 数据中心作为现代信息技术基础设施的核心,承担着处理、存储和传输海量数据的重任。然而,这些庞大的服务器和存储设备在高速运转时,不仅需要大量电力供应,还产生了大量热量。如何平衡电力消耗与有效冷却,成为了数…...
LangChain Chat Model学习笔记
Prompt templates: Few shot、Example selector 一、Few shot(少量示例) 创建少量示例的格式化程序 创建一个简单的提示模板,用于在生成时向模型提供示例输入和输出。向LLM提供少量这样的示例被称为少量示例,这是一种简单但强大的指导生成的方式&…...
嵌入式硬件篇---Keil51中的关键字
文章目录 前言1. 存储类型关键字1.1code作用地址范围用途示例 1.2data作用地址范围用途示例 1.3idata作用地址范围用途示例 1.4xdata作用地址范围用途示例 1.5pdata作用地址范围用途示例 1.6volatile作用用途示例 2. 其他常用关键字2.1bit作用示例 2.2sbit作用示例 2.3sfr / sf…...
《TCP/IP网络编程》学习笔记 | Chapter 20:Windows 中的线程同步
《TCP/IP网络编程》学习笔记 | Chapter 20:Windows 中的线程同步 《TCP/IP网络编程》学习笔记 | Chapter 20:Windows 中的线程同步用户模式和内核模式用户模式同步内核模式同步 基于 CRITICAL_SECTION 的同步内核模式的同步方法基于互斥量对象的同步基于…...
MyBatis 中 #{} 和 ${} 的区别详解
目录 1. #{} 和 ${} 的基本概念 1.1 #{} 1.2 ${} 2. #{} 和 ${} 的工作原理 2.1 #{} 的工作原理 2.2 ${} 的工作原理 3.共同点:动态 SQL 查询 4. 区别:处理方式和适用场景 4.1 处理方式 4.2 适用场景 (1)#{} 的适用场景…...
C++学习之网盘项目单例模式
目录 1.知识点概述 2.单例介绍 3.单例饿汉模式 4.饿汉模式四个版本 5.单例类的使用 6.关于token的作用和存储 7.样式表使用方法 8.qss文件中选择器介绍 9.qss文件样式讲解和测试 10.qss美化登录界面补充 11.QHTTPMULTIPART类的使用 12.文件上传协议 13.文件上传协议…...
Lineageos 22.1(Android 15)制定应用强制横屏
一、前言 有时候需要系统的某个应用强制衡平显示,不管他是如何配置的。我们只需要简单的拿到top的Task下面的ActivityRecord,并判断包名来强制实现。 二、调整wms com.android.server.wm.DisplayRotation /*** Given an orientation constant, return…...
基于deepseek的智能语音客服【第四讲】封装milvus数据库连接池封装
通过工厂模式创建链接 static {// 创建连接池工厂BasePooledObjectFactory<MilvusServiceClient> factory new BasePooledObjectFactory<MilvusServiceClient>() {Overridepublic MilvusServiceClient create() throws Exception {return new MilvusServiceClient…...
【GeeRPC】项目总结:使用 Golang 实现 RPC 框架
文章目录 项目总结:使用 Golang 实现 RPC 框架谈谈 RPC 框架什么是 RPC 框架实现一个 RPC 框架需要什么?项目总结文章结构安排 Part1:消息编码编解码器的实现通信过程 Part2:服务端Accept:阻塞地等待连接请求并开启 go…...
人工智能在医疗影像诊断中的应用与挑战
引言 近年来,人工智能(AI)技术在医疗领域的应用逐渐成为研究热点,尤其是在医疗影像诊断方面。AI技术的引入为医疗影像诊断带来了更高的效率和准确性,有望缓解医疗资源紧张的问题,同时为患者提供更优质的医疗…...
烧结银技术赋能新能源汽车超级快充与高效驱动
烧结银技术赋能新能源汽车超级快充与高效驱动 在新能源汽车领域,高压快充技术的突破与高功率密度驱动系统的创新正成为行业竞争的焦点。比亚迪于 2025 年发布的超级 e 平台,通过整合全域千伏高压架构、兆瓦级闪充技术及碳化硅(SiC࿰…...
大模型幻觉产生的【九大原因】
知识问答推理幻觉产生的原因 1.知识库结构切割不合理 大段落切割向量化 切分太小可以实现更精准化的回复内,向量匹配相似度越高。检索内容碎片化严重、可能包含不符合内容的文本数据。切分太大内容资料更完整,但是会影响相似度,同时更消耗资…...
4小时速通shell外加100例
🔥 Shell 基础——从入门到精通 🚀 🌱 第一章:Shell,简单说! 👶 什么是Shell?它到底能做什么?这章让你快速了解Shell的强大之处! 👶 什么是Shell…...
AD(Altium Designer)更换PCB文件的器件封装
一、确定是否拥有想换的器件PCB封装 1.1 打开现有的原理图 1.2 确定是否拥有想换的器件PCB文件 1.2.1 如果有 按照1.3进行切换器件PCB封装 1.2.2 如果没有 按照如下链接进行添加 AD(Altium Designer)已有封装库的基础上添加器件封装-CSDN博客https://blog.csdn.net/XU15…...
Postgresql 删除数据库报错
1、删除数据库时,报错存在其他会话连接 ## 错误现象,存在其他的会话连接正在使用数据库 ERROR: database "cs" is being accessed by other users DETAIL: There is 1 other session using the database.2、解决方法 ## 终止被删除数据库下…...
人工智能时代——深度探索如何构建开放可控的专利生态体系
# 人工智能时代——深度探索如何构建开放可控的专利生态体系 引言:AI专利革命的战略抉择第一章 战略认知与基本原则1.1 人工智能专利革命的范式重构1.1.1 技术维度变革1.1.2 法律维度挑战1.1.3 文明安全的不可控风险 1.2 战略定位体系构建1.2.1 双循环治理框架的立体…...
✨【数据变形术:联合体在通信协议中的降维打击】✨
(万字长文详解联合体的二进制魔法与工程实践) 🔮 原理解析:内存空间的量子叠加态 文字叙述: 联合体(union)是C语言中最具魔法的数据结构,其所有成员共享同一块内存空间。这种特性使…...
docker compose部署minio报错
背景 部分服务使用docker-compose单节点编排,其中对象存储服务使用minio,在minio中配置了aksk后报错 Error: IAM sub-system is partially initialized, unable to write the IAM forma 解决 minio如果配置了aksk等iam类的配置则需要持久化存储到etcd…...
软件开发通用之状态机初认识-基本概念及简单应用
0 前言 在程序开发阶段(其实也不限于程序,还包含硬件电路设计,协议设计等),无论使用何种语言,何种工具,何种系统,程序的运行必须符合开发者的预设逻辑,而单独通过大脑记…...
蓝桥杯 之 第27场月赛总结
文章目录 习题1.抓猪拿国一2.蓝桥字符3.蓝桥大使4.拳头对决 习题 比赛地址 1.抓猪拿国一 十分简单的签到题 print(sum(list(range(17))))2.蓝桥字符 常见的字符匹配的问题,是一个二维dp的问题,转化为对应的动态规划求解 力扣的相似题目 可以关注灵神…...
适配器模式 (Adapter Pattern)
适配器模式 (Adapter Pattern) 是一种结构型设计模式,它将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。 在现实生活中,适配器的例子随处可见,比如电源适配器,它将不同电压的电流转换为设备所需的电压,确保设备能正…...
操作系统WIN11无法出现WLAN图标(解决方案)
本人操作系统WIN11之后无网络图标 于是在设置里查看了一下,是网卡驱动没了 网上去下载一个驱动类软件自行处理即可。 本人使用手机USB网络连的电脑,然后发现网卡驱动凭空出现了,就很困惑,没有下载驱动就恢复了。...
HCL—我与虚拟机的爱恨情仇[特殊字符][特殊字符][特殊字符]️
时隔了三周,我可能算是了解了虚拟机了吧。自从上一次的安装虚拟机,我与HCL、虚拟机就没有停止过纠缠。 为什么很多win11电脑使用不了HCL,或者无法启动HCL设备? 首先来解答,为什么很多win11电脑使用不了HCL,…...
illustrate:一款蛋白/核酸结构快速渲染为“卡通风格”的小工具
本期向大家介绍一款蛋白/核酸结构快速渲染(卡通风格)的小工具——illustrate。放心!本期完全不涉及代码,不折腾人,请放心食用。 结构渲染效果示例如下: PDB ID: 1ttt 该小工具适用绘制蛋白或复合物整体轮廓…...
Linux上位机开发实战(能用的开发板计算资源)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 大家所能想到的嵌入式上位机开发,如果是linux,同时涉及到嵌入式的话,一般都会认为是把pc linux的软件port到板子…...