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

红黑树的封装

一、封装思路

在 STL 中 map set 的底层就是封装了一棵红黑树。

其中连接红黑树和容器的是迭代器,map set 暴露出的接口都不是自己写的,而是红黑树写的,外部接口封装红黑树接口。

所以写出红黑树为 map set 写的接口,再在上层的 map set 类中包装一下即可。

之前的红黑树就是单纯的在树上插入节点,为了实现 map set 就需要红黑树再实现迭代器。

二、红黑树细节实现

1、迭代器

本质就是封装了一个节点,用于遍历红黑树找到目标值。

(1)整体设计

与链表迭代器一样,需要迭代器重载解引用和箭头,所以模板依旧设计成:

template<class T, class Ref, class Ptr>

来适应 const 迭代器的复用。

(2)重载解引用

// 解引用迭代器是取数据
Ref operator*()
{return _node->_data;
}

(3)重载箭头

// 取数据的地址
Ptr operator->()
{return &(_node->_data);
}

(4)重载不等于

bool operator!=(const Self& it)
{return _node != it._node;
}

(5)后置++

// 1.如果右子树存在,访问右子树的最左节点
// 2.如果右子树不存在,如果我是父亲的左,那就访问父亲
//   如果我是父亲的右,表示父亲也完了,向上判断,直到是左孩子
Self& operator++()
{if (_node->_right){Node* cur = _node->_right;while (cur->_left)cur = cur->_left;_node = cur;}else{Node* cur = _node;while (cur->_parent && cur == cur->_parent->_right)cur = cur->_parent;_node = cur->_parent;}return *this;
}

(6)后置--

// 1.如果左子树存在,返回左子树的最右节点
// 2.如果左子树不存在,如果是父亲的右孩子,返回根
//   如果是父亲的左孩子,向上找直到是右孩子
Self& operator--()
{Node* cur = _node;if (_node->_left){while (cur->_right)cur = cur->_right;_node = cur;}else{while (cur && cur == cur->_parent->_left)cur = cur->_parent;_node = cur->_parent;}return *this;
}

2、红黑树

到这里迭代器已经实现完毕,要把裸的迭代器实现出不同的形式花样就是在红黑树这一层实现的。

(1)整体设计

从这里开始就要考虑如何把容器与红黑树相关联。

难点一

 map 是 kv 模型,set 是 key 模型,类型都不一样,怎么防止在一份红黑树代码中参数的冲突?

库里面的解决办法是:template<class K, class T>

这里的 T 是存放的数据类型,即 map 是 pair<K, V>,set 是 K,这样至少能传入正确的参数了。

但是红黑树主要功能插入删除的比较参数是 key,所以直接传入的参数 T 用于比较(map 的 pair<K, V> 比较逻辑是 K 大的就返回,K 不大就 V 大的返回,显然不符合比较逻辑)是不行的,我们需要都是比较 K,所以还需要一个内部类提取 map set 的 key 值。

所以最终的红黑树模板参数如下:

template<class K, class T, class KeyOfT>

K 是 key 的类型,T 是容器存储的数据类型,KeyOfT 是分别在 map 和 set 中实现的内部类分别提取其中的 key 用于插入删除函数的比较。

难点二

迭代器分为 const 迭代器和非 const 迭代器,所以在红黑树中也要封装。

不用写两份迭代器代码,之前迭代器的模板参数就起作用了:其实 const 和非 const 的区别就是指向的内容不能修改,就是解引用和箭头的重载返回值不能被修改,利用模板实例化就能解决问题:

// 红黑树中定义两个迭代器,模板参数不同即可
typedef __RBTreeIterator<T, T&, T*> Iterator;
typedef __RBTreeIterator<T, const T&, const T*> ConstIterator;

(2)构造析构

由于已经要和容器接轨了,所以要考虑深浅拷贝问题,这里封装了常见的默认成员函数

RBTree() = default; // 由于已经写了拷贝构造,强制生成默认构造// 私有的概念只针对于类外,类内可以访问其他对象的私有成员
RBTree(const RBTree<K, T, KeyOfT>& tree)
{_root = Copy(tree._root);
}RBTree<K, T, KeyOfT>& operator=(RBTree<K, T, KeyOfT> tree)
{swap(_root, tree._root);
}~RBTree()
{Destroy(_root);_root = nullptr;
}

(3)迭代器封装

在迭代器类中已经处理了迭代器的使用逻辑,在红黑树这一层就是封装容器的迭代器常用功能

Iterator begin()
{Node* leftMin = _root;while (leftMin && leftMin->_left)leftMin = leftMin->_left;return leftMin;
}Iterator end()
{return Iterator(nullptr);
}ConstIterator begin() const
{Node* leftMin = _root;while (leftMin && leftMin->_left)leftMin = leftMin->_left;return leftMin;
}ConstIterator end() const
{return ConstIterator(nullptr);
}

注意 const 迭代器函数后面需要加 const 构成函数重载。

(4)insert 改造

和库里面保持一致,插入函数返回插入元素的迭代器和是否插入成功的 pair

为了比较的正确性要利用内部类 KeyOfT 来取出数据的 key 进行比较

pair<Iterator, bool> insert(const T& data)
{if (_root == nullptr){_root = new Node(data);_root->_col = BLACK;return {_root, true};}Node* cur = _root;Node* parent = cur;KeyOfT kot;// 1.像搜索二叉树一样插入节点curwhile (cur){if (kot(cur->_data) > kot(data)){parent = cur;cur = cur->_left;}else if (kot(cur->_data) < kot(data)){parent = cur;cur = cur->_right;}elsereturn {cur, false};}cur = new Node(data);Node* newnode = cur;if (kot(parent->_data) < kot(data))parent->_right = cur;elseparent->_left = cur;cur->_parent = parent;// 新插入是红色,如果父亲是黑色就没事while (parent && parent->_col == RED){Node* g = parent->_parent;Node* uncle = parent == g->_left ? g->_right : g->_left;// 情况一:叔叔存在且为红,u p 变黑,g变红,向上if (uncle && uncle->_col == RED){uncle->_col = parent->_col = BLACK;g->_col = RED;cur = g;parent = cur->_parent;}// 情况二:叔叔存在且为黑或叔叔不存在else{// u parent cur 的位置决定的是左右单旋双旋//       gB              pB//    pR     u   ->   cR     gR// cR                            uif (cur == parent->_left && parent == g->_left){RotateR(g);parent->_col = BLACK;g->_col = RED;}//       gB              gB            cB//    pR     u   ->   cR     u  ->  pR    gR//       cR         pR                       uelse if (cur == parent->_right && parent == g->_left){RotateL(parent);RotateR(g);cur->_col = BLACK;g->_col = RED;}//       gB                pB//     u    pR    ->    gR    cR//             cR     u                        else if (cur == parent->_right && parent == g->_right){RotateL(g);g->_col = RED;parent->_col = BLACK;}//       gB             gB                 cB//    u     pR   ->   u    cR     ->    gR    pR//       cR                   pR      u                  else if (cur == parent->_left && parent == g->_right){RotateR(parent);RotateL(g);cur->_col = BLACK;g->_col = RED;}elseassert(false);break;}}_root->_col = BLACK;return {newnode, true};
}

三、容器细节实现

首先容器的实现共性是 map set 上层确确实实只传入 <K, V> 和 <K>,是底层红黑树为了适应容器,底层红黑树的实例化是 <K, pair<K, V>, KeyOfT> 和 <K, K, KeyOfT>

其次两者都要实现各自的 KeyOfT 内部类来告诉底层红黑树要怎么取到 key 值。

最后容器封装底层红黑树写好的迭代器代码交给外部使用。

1、set 实现

template<class K>
class set
{struct SetKeyOfT{const K& operator()(const K& key){return key;}};
public:typedef typename RBTree<K, const K, SetKeyOfT>::Iterator iterator;typedef typename RBTree<K, const K, SetKeyOfT>::ConstIterator const_iterator;iterator begin(){return _t.begin();}iterator end(){return _t.end();}const_iterator begin() const{return _t.begin();}const_iterator end() const{return _t.end();}iterator find(const K& key){return _t.find(key);}pair<iterator, bool> insert(const K& key){return _t.insert(key);}
private:RBTree<K, const K, SetKeyOfT> _t;
};

2、map 实现

template<class K, class V>
class map
{struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};
public:typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::Iterator iterator;typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::ConstIterator const_iterator;iterator begin(){return _t.begin();}iterator end(){return _t.end();}const_iterator begin() const{return _t.begin();}const_iterator end() const{return _t.end();}iterator find(const K& key){return _t.find(key);}pair<iterator, bool> insert(const pair<K, V>& kv){return _t.insert(kv);}V& operator[](const K& key){pair<iterator, bool> ret = _t.insert({ key, V() });return ret.first->second;}
private:RBTree<K, pair<const K, V>, MapKeyOfT> _t;
};

值得一提的是 map 还要重载 [],其实现逻辑已经在博客map和set-CSDN博客解释过。

相关文章:

红黑树的封装

一、封装思路 在 STL 中 map set 的底层就是封装了一棵红黑树。 其中连接红黑树和容器的是迭代器&#xff0c;map set 暴露出的接口都不是自己写的&#xff0c;而是红黑树写的&#xff0c;外部接口封装红黑树接口。 所以写出红黑树为 map set 写的接口&#xff0c;再在上层的…...

Java 泛型<? extends Object>

在 Java 泛型中&#xff0c;<? extends Object> 和 <?> 都表示未知类型&#xff0c;但它们在某些情况下有细微的差异。泛型的引入是为了消除运行时错误并增强类型安全性&#xff0c;使代码更具可读性和可维护性。 在 JDK 5 中引入了泛型&#xff0c;以消除编译时…...

TensorFlow简单的线性回归任务

如何使用 TensorFlow 和 Keras 创建、训练并进行预测 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与预测 7. 保存与加载模型 8.完整代码 1. 数据准备与预处理 我们将使用一个简单的线性回归问题&#xff0c;其中输入特征 x 和标…...

解码大数据的四个V:体积、速度、种类与真实性

解码大数据的四个V&#xff1a;体积、速度、种类与真实性 在大数据领域&#xff0c;有一个大家耳熟能详的概念——“四个V”&#xff1a;Volume&#xff08;体积&#xff09;、Velocity&#xff08;速度&#xff09;、Variety&#xff08;种类&#xff09;、Veracity&#xff…...

【单层神经网络】基于MXNet的线性回归实现(底层实现)

写在前面 基于亚马逊的MXNet库本专栏是对李沐博士的《动手学深度学习》的笔记&#xff0c;仅用于分享个人学习思考以下是本专栏所需的环境&#xff08;放进一个environment.yml&#xff0c;然后用conda虚拟环境统一配置即可&#xff09;刚开始先从普通的寻优算法开始&#xff…...

深入解析 posix_spawn():高效的进程创建方式(中英双语)

深入解析 posix_spawn()&#xff1a;高效的进程创建方式 1. 引言 在 Unix/Linux 系统中&#xff0c;传统的进程创建方式主要依赖 fork() 和 exec() 组合。但 fork() 在某些情况下可能存在性能瓶颈&#xff0c;特别是当父进程占用大量内存时&#xff0c;fork() 仍然需要复制整…...

2024-我的学习成长之路

因为热爱&#xff0c;无畏山海...

【Java异步编程】基于任务类型创建不同的线程池

文章目录 一. 按照任务类型对线程池进行分类1. IO密集型任务的线程数2. CPU密集型任务的线程数3. 混合型任务的线程数 二. 线程数越多越好吗三. Redis 单线程的高效性 使用线程池的好处主要有以下三点&#xff1a; 降低资源消耗&#xff1a;线程是稀缺资源&#xff0c;如果无限…...

前缀和多种基础

前缀和加法 #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int n; const int N 1e310; int arr[N]; int pre[N]; int org[N]; int main(void) {cin >> n;for(int i 1 ; i < n ; i){cin >> arr[i];pre[i] …...

关于贪心学习的文笔记录

贪心&#xff0c;顾名思义就是越贪越好&#xff0c;越多越有易&#xff0c;他给我的感觉是&#xff0c;通常是求最大或最小问题&#xff0c;相比于动态规划贪心让人更加琢磨不透&#xff0c;不易看出方法&#xff0c;为此在这记录我所见过的题型和思维方法&#xff0c;以便回头…...

蓝桥杯思维训练营(三)

文章目录 题目详解680.验证回文串 II30.魔塔游戏徒步旅行中的补给问题观光景点组合得分问题 题目详解 680.验证回文串 II 680.验证回文串 II 思路分析&#xff1a;这个题目的关键就是&#xff0c;按照正常来判断对应位置是否相等&#xff0c;如果不相等&#xff0c;那么就判…...

农历2025开始 笔记

2/3 Hey everyone! The Chinese New Year holiday is over. I spent over ten days back home, and honestly, I feel even more exhausted than when I’m working. Yesterday, I drove for 13 hours straight and finally made it back. In a couple of days, I’ll officia…...

VR触感数据手套:触感反馈赋予虚拟交互沉浸式体验

随着动作捕捉技术的蓬勃发展&#xff0c;动捕数据手套成为了手部动作捕捉与虚拟交互的便捷工具&#xff0c;为人们打开了通往虚拟世界的新大门。在众多产品中&#xff0c;mHand Pro作为一款多功能兼具的VR动作捕捉数据手套&#xff0c;凭借其卓越的性能&#xff0c;在手部动作捕…...

6 [新一代Github投毒针对网络安全人员钓鱼]

0x01 前言 在Github上APT组织“海莲花”发布存在后门的提权BOF&#xff0c;通过该项目针对网络安全从业人员进行钓鱼。不过其实早在几年前就已经有人对Visual Studio项目恶意利用进行过研究&#xff0c;所以投毒的手法也不算是新的技术。但这次国内有大量的安全从业者转发该钓…...

基于LabVIEW的Modbus-RTU设备通信失败问题分析与解决

在使用 LabVIEW 通过 Modbus-RTU 协议与工业设备进行通信时&#xff0c;可能遇到无法正常发送或接收指令的问题。常见原因包括协议参数配置错误、硬件连接问题、数据帧格式不正确等。本文以某 RGBW 控制器调光失败为例&#xff0c;提出了一种通用的排查思路&#xff0c;帮助开发…...

【环境搭建】1.1源码下载与同步

目录 写在前面 一&#xff0c;系统要求 二&#xff0c;安装depot_tools 三&#xff0c;获取代码 四&#xff0c;代码同步 五&#xff0c;代码结构 写在前面 当前的开发背景是基于Google的开源Chromium&#xff0c;来开发Android设备的浏览器方案。 一&#xff0c;系统要…...

从理论到实践:Linux 进程替换与 exec 系列函数

个人主页&#xff1a;chian-ocean 文章专栏-Linux 前言&#xff1a; 在Linux中&#xff0c;进程替换&#xff08;Process Substitution&#xff09;是一个非常强大的特性&#xff0c;它允许将一个进程的输出直接当作一个文件来处理。这种技术通常用于Shell脚本和命令行操作中…...

增删改查(CRUD)操作

文章目录 MySQL系列&#xff1a;1.CRUD简介2.Create(创建)2.1单行数据全列插入2.2 单行数据指定插入2.3 多⾏数据指定列插⼊ 3.Retrieve(读取)3.1 Select查询3.1.1 全列查询3.1.2 指定列查询3.1.3 查询字段为表达式&#xff08;都是临时表不会对原有表数据产生影响&#xff09;…...

算法竞赛(Python)-堆栈

文章目录 一 基础知识二 题目有效的括号字符串解码 一 基础知识 堆栈&#xff08;Stack&#xff09;&#xff1a;简称为栈。一种线性表数据结构&#xff0c;是一种只允许在表的一端进行插入和删除操作的线性表。   我们把栈中允许插入和删除的一端称为 「栈顶&#xff08;top…...

【C++篇】位图与布隆过滤器

目录 一&#xff0c;位图 1.1&#xff0c;位图的概念 1.2&#xff0c;位图的设计与实现 1.5&#xff0c;位图的应用举例 1.4&#xff0c;位图常用应用场景 二&#xff0c;布隆过滤器 2.1&#xff0c;定义&#xff1a; 2.2&#xff0c;布隆过滤器的实现 2.3&#xff0c; 应…...

deeplabv3+街景图片语义分割,无需训练模型,看不懂也没有影响,直接使用,cityscapes数据集_6

目录 1、下载链接1.1、CSDN链接&#xff0c;含权重文件直接使用&#xff0c;建议直接下这个&#xff0c;还不限速。1.2 Github链接&#xff1a;2、下载代码&#xff0c;下载预训练好的权重3、预测代码4、像素提取&#xff0c;或者说类别提取5、文档部分内容截图6、其他数据处理…...

DeepSeek 原理解析:与主流大模型的差异及低算力优势

在人工智能大模型蓬勃发展的浪潮中&#xff0c;DeepSeek 以其独特的技术路线和出色的性能表现脱颖而出。与主流大模型相比&#xff0c;DeepSeek 不仅在技术原理上有着显著的差异&#xff0c;还展现出了在较低算力下达到 OpenAI API 水平的卓越能力。本文将深入剖析这些独特之处…...

OpenAI推出Deep Research带给我们怎样的启示

OpenAI 又发新产品了&#xff0c;这次是面向深度研究领域的智能体产品 ——「Deep Research」&#xff0c;貌似被逼无奈的节奏… 在技术方面&#xff0c;Deep Research搭载了优化后o3模型并通过端到端强化学习在多个领域的复杂浏览和推理任务上进行了训练。因没有更多的技术暴露…...

第三周 树

猫猫和企鹅 分数 10 全屏浏览 切换布局 作者 姜明欣 单位 河北大学 王国里有 nn 个居住区&#xff0c;它们之间有 n−1 条道路相连&#xff0c;并且保证从每个居住区出发都可以到达任何一个居住区&#xff0c;并且每条道路的长度都为 1。 除 1号居住区外&#xff0c;每个居…...

【挖矿——前缀和】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 2e610; int l[N], r[N]; int n, m, ans; int main() {cin >> n >> m;for(int i 1; i < n; i){int p;cin >> p;if(p < 0) l[-p];else r[p];}for(int i 1; i < m; i)l[…...

整个 PVE 系统崩溃后,怎么恢复 PVE 给虚拟机分配的虚拟硬盘中的数据

背景 我有一块 ssd 用于 PVE 系统和 虚拟机 安装&#xff0c;还有一块 HDD 用来存储数据。这个HDD按照 把 PVE 下的机械硬盘&#xff08;非SSD系统盘&#xff09;分配给虚拟机使用 进行挂载和配置。主要过程是 PVE中 “数据中信” -> “存储” -> “添加” -> “目录…...

Java循环操作哪个快

文章目录 Java循环操作哪个快一、引言二、循环操作性能对比1、普通for循环与增强for循环1.1、代码示例 2、for循环与while循环2.1、代码示例 3、循环优化技巧3.1、代码示例 三、循环操作的适用场景四、使用示例五、总结 Java循环操作哪个快 一、引言 在Java开发中&#xff0c;…...

【C++ STL】vector容器详解:从入门到精通

【C STL】vector容器详解&#xff1a;从入门到精通 摘要&#xff1a;本文深入讲解C STL中vector容器的使用方法&#xff0c;涵盖常用函数、代码示例及注意事项&#xff0c;助你快速掌握动态数组的核心操作&#xff01; 一、vector概述 vector是C标准模板库&#xff08;STL&am…...

差值 dp 入门

引入 有一类问题&#xff1a;两个人交替选 n n n 个数 a [ 1 … n ] a[1 \dots n] a[1…n]&#xff0c;要使得每个人分得的数大小之和相等&#xff08;或差值尽可能小&#xff09;&#xff0c;同时尽可能保证分得的总金额尽可能大。 这类问题的解法之一是 dp。 有一个通用…...

使用mybatisPlus插件生成代码步骤及注意事项

使用mybatisPlus插件可以很方便的生成与数据库对应的PO对象&#xff0c;以及对应的controller、service、ImplService、mapper代码&#xff0c;生成这种代码的方式有很多&#xff0c;包括mybatis-plus提供的代码生成器&#xff0c;以及idea提供的代码生成器&#xff0c;无论哪一…...

fpga系列 HDL:XILINX Vivado 常见错误 “在线逻辑分析Debug时ALL_CLOCK没有选项”

错误描述 解决方法 需要先将线路设计的每个模块导出IP&#xff0c;然后再导出HDL Wrapper&#xff1a; CG 此外&#xff0c;如果没有进行PIN PLAN或者对PIN的电压属性进行设置&#xff0c;可能导致 Implentation 成功但是Generate Bitstream 失败。...

Vue3学习笔记-条件渲染和列表渲染-3

一、条件渲染 在Vue中&#xff0c;提供了四种条件渲染&#xff1a; v-ifv-elsev-else-ifv-show v-if:指令用于表达式返回为真时才被渲染 <template><button v-if"flag">{{button_text}}</button> </template> <script> export def…...

寒假day10

第十天&#xff1a;请写出以下几个数据的类型 整数 a int a的地址 int* 存放a的数组b …...

Shell特殊状态变量以及常用内置变量总结

目录 1. 特殊的状态变量 1.1 $?&#xff08;上一个命令的退出状态&#xff09; 1.2 $$&#xff08;当前进程的 PID&#xff09; 1.3 $!&#xff08;后台进程的 PID&#xff09; 1.4 $_&#xff08;上一条命令的最后一个参数&#xff09; 2.常用shell内置变量 2.1 echo&…...

javaEE初阶————多线程初阶(1)

多线程初阶———— 1&#xff0c;认识线程 1.1 概念 1&#xff09;线程是什么 线程就是一个“执行流”&#xff0c;可以理解为程序执行的最小单位&#xff1b; 可以看成轻量级的进程&#xff1b; 2&#xff09;为啥要有线程 “并发编程” 的需要&#xff0c;但是我们不…...

DOM 操作入门:HTML 元素操作与页面事件处理

DOM 操作入门:HTML 元素操作与页面事件处理 DOM 操作入门:HTML 元素操作与页面事件处理什么是 DOM?1. 如何操作 HTML 元素?1.1 使用 `document.getElementById()` 获取单个元素1.2 使用 `document.querySelector()` 和 `document.querySelectorAll()` 获取多个元素1.3 创建…...

排序算法--桶排序

核心思想为分区间排序后合并。适用于数据均匀分布在一个范围内&#xff0c;或浮点数排序或范围明确的数据。如果需要处理整数或其他数据范围&#xff0c;可以通过调整BUCKET_RANGE的计算方式实现&#xff0c;例如对[0,100)的整数排序&#xff1a; int index arr[i] / 10; // …...

Baklib推动数字化内容管理解决方案助力企业数字化转型

内容概要 在当今信息爆炸的时代&#xff0c;数字化内容管理成为企业提升效率和竞争力的关键。企业在面对大量数据时&#xff0c;如何高效地存储、分类与检索信息&#xff0c;直接关系到其经营的成败。数字化内容管理不仅限于简单的文档存储&#xff0c;更是整合了文档、图像、…...

读书笔记--分布式架构的异步化和缓存技术原理及应用场景

本篇是在上一篇的基础上&#xff0c;主要对分布式应用架构下的异步化机制和缓存技术进行学习&#xff0c;主要记录和思考如下&#xff0c;供大家学习参考。大家知道原来传统的单一WAR应用中&#xff0c;由于所有数据都在同一个数据库中&#xff0c;因此事务问题一般借助数据库事…...

Hive存储系统全面测试报告

引言 在大数据时代&#xff0c;数据存储和处理技术的重要性日益凸显。Apache Hive作为一个基于Hadoop的数据仓库工具&#xff0c;因其能够提供类SQL查询功能&#xff08;HiveQL&#xff09;而广受欢迎。Hive的设计初衷是为了简化大数据集的查询和管理&#xff0c;它允许用户通…...

【产品经理学习案例——AI翻译棒出海业务】

前言&#xff1a; 本文主要讲述了硬件产品在出海过程中&#xff0c;翻译质量、翻译速度和本地化落地策略是硬件产品规划需要考虑的核心因素。针对不同国家&#xff0c;需要优化翻译质量和算法&#xff0c;关注市场需求和文化差异&#xff0c;以便更好地满足当地用户的需求。同…...

Golang 并发机制-3:通道(channels)机制详解

并发编程是一种创建性能优化且响应迅速的软件的强大方法。Golang&#xff08;也称为 Go&#xff09;通过通道&#xff08;channels&#xff09;这一特性&#xff0c;能够可靠且优雅地实现并发通信。本文将揭示通道的概念&#xff0c;解释其在并发编程中的作用&#xff0c;并提供…...

【LeetCode 刷题】回溯算法(2)-分割问题

此博客为《代码随想录》二叉树章节的学习笔记&#xff0c;主要内容为回溯算法分割问题相关的题目解析。 文章目录 131.分割回文串93.复原IP地址 131.分割回文串 题目链接 class Solution:def partition(self, s: str) -> List[List[str]]:res, path [], []def check(s: …...

前端力扣刷题 | 6:hot100之 矩阵

73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 法一&#xff1a; var setZeroes function(matrix) {let setX new Set(); // 用于存储需要置零的行索引let setY new Set(); //…...

pytorch实现半监督学习

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 半监督学习&#xff08;Semi-Supervised Learning&#xff0c;SSL&#xff09;结合了有监督学习和无监督学习的特点&#xff0c;通常用于部分数据有标签、部分数据无标签的场景。其主要步骤如下&#xff1a; 1. 数…...

X Window System 架构概述

X Window System 架构概述 1. X Server 与 X Client ​ 这里引入一张维基百科的图&#xff0c;在Linux系统中&#xff0c;若用户需要图形化界面&#xff0c;则可以使用X Window System&#xff0c;其使用**Client-Server**架构&#xff0c;并通过网络传输相关信息。 ​ ​ X…...

中国证券基本知识汇总

中国证券市场是一个多层次、多领域的市场&#xff0c;涉及到各种金融工具、交易方式、市场参与者等内容。以下是中国证券基本知识的汇总&#xff1a; 1. 证券市场概述 证券市场&#xff1a;是指买卖证券&#xff08;如股票、债券、基金等&#xff09;的市场。证券市场可以分为…...

虚幻基础17:动画蓝图

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 animation blueprint图表&#xff08;Graph&#xff09;&#xff1a; 编辑动画逻辑。变量&#xff08;Variables&#xff09;&#xff1a; 管理动画参数。函数&#xff08;Functions&#xff09;&#xff1a; 自定义…...

初入机器学习

写在前面 本专栏专门撰写深度学习相关的内容&#xff0c;防止自己遗忘&#xff0c;也为大家提供一些个人的思考 一切仅供参考 概念辨析 深度学习&#xff1a; 本质是建模&#xff0c;将训练得到的模型作为系统的一部分使用侧重于发现样本集中隐含的规律难点是认识并了解模型&…...

中间件的概念及基本使用

什么是中间件 中间件是ASP.NET Core的核心组件&#xff0c;MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲&#xff1a;Tomcat、WebLogic、Redis、IIS&#xff1b;狭义上来讲&#xff0c;ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件…...