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

C++——红黑树

作者:几冬雪来

时间:2023年12月7日

内容:C++——红黑树讲解

目录

前言: 

红黑树的概念: 

红黑树的性质:

红黑树的路径计算: 

最长路径和最短路径:

AVL树与红黑树的区别: 

红黑树的框架: 

红黑树插入节点: 

插入节点颜色的变化:

颜色变化的特殊情况: 

变色与旋转: 

判断是否为红黑树: 

代码: 

结尾: 


前言: 

在上一篇博客中我们讲解了在C++两棵重要的树中的一棵树,也就是AVL树。而另一棵树就是今天要对其讲解的红黑树。而红黑树也算C++板块的一个重要的知识点,在解题的时候经常被使用。

 

红黑树的概念: 

在上一篇博客讲解AVL树的时候就有谈到过,红黑树和AVL树都属于二叉搜索树的一个延伸,二者的做法差不多,但是其性质却不一样

这里的红黑树,顾名思义就是在每个结点上都增加一个储存为表示该节点的颜色,可以说红或者黑色。而对比起之前讲解的C++的AVL树,红黑树会在一定程度上更优一点。 

红黑树在一定程度上占优,这是因为AVL树过于严格了,它必须保证最高的结点减去最短结点后高度要小于2或者大于-2

这个地方红黑树的做法是,使得每个结点都有红黑两种颜色限制达到最长路径不超过最短路径的两倍

但是这种行为也有它的弊端,那就是对比AVL树,AVL树的平衡是几乎平衡而红黑树的平衡只是近似平衡而且,且在插入相同数量结点的情况下红黑树的高度要较高于AVL树

虽然红黑树的高度相较于AVL树要高,但是其效率却不输AVL树

红黑树的性质:

在讲解完了红黑树的概念之后,接下来就来说一说红黑树的性质

这里看一下红黑树的4个性质,第一个要求每个结点不是黑的就是红色的

接下来就是规定了根节点必须是黑色的

第三条性质讲解了,在红黑树中的任何路径没有连续的两个同为红色的结点

这个地方的最后一条说明了,每条路径都包含了相同数量的黑色结点

红黑树的路径计算: 

在上面最后一条性质讲了,红黑树的每条路径都包含了相同数量的黑色结点

那么这个地方就延伸出一个问题,红黑树要怎么去数它路径的多少,就以刚刚上边的那张红黑树的图为例:

这里路径数量的计算方式是,从根节点到空节点算一条路径,因此要算该红黑树有多少路径的话,最优的方法就是看它空节点的数量是多少

最长路径和最短路径:

在了解完了红黑树路径的计算后,接下来我们就来看看它的最长和最短路径是如何得出的。在AVL树中我们可以得知,最长路径和最短路径是相互限制的,最长路径不能超过最短路径的高度差不超过1

而在红黑树中最长路径和最短路径有了新的变化

首先红黑树的最短路径如上图的左子树,全为黑色结点的路径就为最短路径。而最长路径则是一红一黑相间的路径

AVL树与红黑树的区别: 

在初步了解完了红黑树之后,接下来就是要让红黑树与先前学习的AVL树做对比,对比二者的优缺点

首先就是二者的时间复杂度

从图中可以看出红黑树的时间复杂度是AVL树的两倍,但是先前我们又讲解过红黑树要优于AVL树,这是因为二者处于同一量级,对此一倍与两倍对编译器的效率影响可以忽略不计

话虽如此,但是AVL树看起来时间复杂度是比AVL树小的,同时前面也有说明AVL树是被严格控制平衡的,红黑树只是近似平衡

但是AVL树严格控制平衡会有一定的代价,那就是AVL树在插入和删除的时候需要进行大量的旋转操作,而红黑树对比AVL树不需要大量的旋转操作

红黑树的框架: 

和书写AVL一样,书写红黑树也要有一个它自己的框架,又因为红黑树不用动用到平衡因子,因此也就不需要一个整形来存放平衡因子的值,二者框架的代码也会略微不同。

在这个地方依旧的要创建一个左结点,一个右结点和一个父结点。而后再借用map的pair创建一个_kv

与AVL在这个地方创建一个整形类型的_bf来储存平衡因子不同,红黑树因为没有平衡因子所以不需要创建_bf来使用

但是红黑树在这里涉及到了结点的颜色,因此此处要用一个枚举函数枚举出RED和BLACK两种颜色

再然后对它们进行初始化,这里的col就从RED与BLACK中随机选一个颜色进行初始化即可。、 

红黑树插入节点: 

在书写完了框架之后,接下来就是红黑树节点的插入

因为红黑树和AVL树都是二叉搜索树的延伸,因此在书写插入代码的时候二者十分的相似,这里我们就可以使用CV操作,将AVL树插入的代码拷贝过来

但是在红黑树的性质那里有规定,根节点的颜色必须为黑色,因此当根节点为空第一次插入结点的时候,这里要将这个节点的颜色设计为黑色

而在插入首个节点,接下来每个新插入节点的颜色会带来一些问题,也就是我们它的节点颜色是红色还是黑色

要解决这个问题,这里需要返回到之前红黑树性质的4条规则那里

在这里着重要关注的是第3条与第4条规则

如果插入的结点颜色为黑色的话,这个地方可能会使得第四条规则违规,因为规则里面有说要保证每个路径的黑色节点的个数相同,要是增加的节点颜色为黑色的话,最终会导致该路径的黑节点的个数与其他路径的不一致

如果新插入节点为红色,那这个地方要保证期父节点的颜色不为红色

因此插入的新节点颜色只能为红色,并且要对新节点的父节点进行判断

插入节点颜色的变化:

在上文我们讲解到红黑树插入的新节点的颜色必然是红色,而且如果插入的新节点的父节点也会红色的话,这里就要进行节点变色的操作

首先就是将新插入的节点定义为cur,接下来将它父节点定义为parent同时将parent的父节点的另一边节点定义为uncle

如果新插入的节点cur与parent的颜色同为红色的话,这里就违反了规则不能有两个红色的节点连续

因此parent结点就需要更改为黑色,又因为在红黑树中每条路径黑色结点的数量必须都一样,所以uncle要换为黑色,同时也因为每条路径黑色节点的数量不能改变,所以uncle的父节点要换为红色,如果parent的父节点为红且不为根节点的话,我们就继续向上处理。 

因此这个地方就总结出来了几个情况: 

1.如果grandfather没有父亲,也就是grandfather为根,只需要将其变黑即可

2.如果grandfather有父亲,且它的父亲为黑色,则结束运行

3. 如果grandfather有父亲,它的颜色为红色,这里就要向上处理,cur为第一次修改的grandfather位置

颜色变化的特殊情况: 

在什么我们得知了插入节点后节点颜色变化的规律,插入的必然是红节点,如果其父节点与uncle也为红节点的话,就要将它与uncle节点都改为黑色

接下来再判断它们的grandfather的颜色与有无父节点来决定要不要继续向上处理

但是这里可能会出现一些特殊的情况

就如同上图,新添加的cur节点它的父节点为红色,但是这里并没有uncle节点

这样就意味着,这个地方我们不能直接去修改parent与grandfather的颜色,如果修改后就会和上图一样,有一条路径的黑色节点的个数变少了。

这个地方的另一种特殊情况则是增加节点导致了最长路径超过了最短路径的两倍,在这种情况下我们也不能只是单纯的对其进行换色操作

而且这里为了解决这些问题就要利用到AVL树中的旋转操作了,同时这里的旋转也是有单旋和双旋的做法

就拿最长路径超过了最短路径的两倍的特殊情况来举例,这个地方要使这棵错误的红黑树变为正常的红黑树

首先就是以值为25的结点为旋转点进行一次右旋的操作,使得最长路径与最短路径在两倍或者两倍以内,再旋转后才能判断后对节点进行上色操作

同样的红黑树没有uncle节点也是通过旋转再上色的操作完成的

因此这里我们就得出了一些特殊情况:

1.uncle节点不存在的情况

2.uncle节点存在,且该节点颜色为黑

3.uncle节点存在,且该节点颜色为红

同时也对上面特殊情况的处理做了总结:

1.如果uncle存在且为红,则进行变色操作后再向上处理

2.如果uncle不存在或者存在且为黑,则先进行旋转操作后再进行换色操作 

这里我们也能看出红黑树插入后的旋转或者变色操作,关键还是要看uncle。 

变色与旋转: 

在进行完了节点插入的操作,并且也清楚的了解了红黑树的节点颜色的一些规矩,并且也知道了红黑树的变色与旋转操作,关键是在于uncle节点的情况

但是使得上下两个连接的节点都呈现红色的情况不单单只有parent为红节点,cur为新插入的节点这一种操作而已

下来我们就来讲解在哪些情况会出现下上下两个连接节点都为红色的情况

在这里的c,d,e处如果是只有一个黑节点的局部树的话有4种节点形状的插入,外加上新插入的节点有4个位置能插入,因此能计算出来这里最后能有256种(4*4*4*4)插入的结果

并且从上图我们也可以看出来使得上下两个节点都变为红色的不止只有新插入节点的情况,也可能是新插入的节点使得grandfather变为红色,让grandfather和它的父节点颜色相同。 

因此红黑树在这里有无数种组合情况。 

知道红黑树在什么情况下要对其节点进行变色,在什么情况下要对其节点进行旋转操作后,接下来我们就来书写它的代码。

因为在红黑树中我们可能要不断的向上处理,首先就是一个循环判断新插入节点的父节点存不存在存在的同时它的颜色是不是为红色,只有同时满足两个条件才能进入循环

接下来就是确定父节点的父节点,接下来如果parent节点为grandfather节点的左边的话,这个地方我们就能确定uncle节点的位置

再下来还是判断,如果uncle节点存在且为红色的话,这个地方我们就将parent与uncle节点更改为黑色,再将grandfather节点更改为红色

如果第一次变色结束后修改后的parent节点不存在或者存在但是为黑的话,这里的做法就是将根节点的颜色改为黑色

接下来就是几种比较特殊的情况,上图这种就是uncle节点不存在的情况,这种情况就需要进行旋转操作

而下面的则是存在uncle,但是parent节点为红uncle节点的颜色为黑色的情况。在这种情况下cur节点不可能为新插入的节点,因为这会导致它们路径上的黑节点不同

与此同时,c处应该是有一个黑色节点的局部树,d与e两个位置可以为红节点也可以为空

并且这里旋转的代码可以从AVL树那边CV过来,唯一需要更改的就是将平衡因子删除

这个地方在原parent为grandfather的左节点的基本上进行判断,这里如果uncle不存在或者uncle节点为黑,对其进行分类讨论

如果parent为grandfather的左节点,cur也为parent的左节点,这里就像AVL树一样,以grandfather为旋转点进行一次右旋,而后将parent与grandfather的节点颜色进行更改

如果cur为parent的右节点,这里也是和AVL树一样进行双旋后再对节点颜色进行更改

在上面我们就以parent为grandfather的左节点写了变色和处理的办法

这个地方则继续写出当parent为grandfather的右节点的代码,其变化和旋转的方法不变,唯一变化的则是方向可能会发生改变

判断是否为红黑树: 

在书写完了红黑树之后,接下来就是一个重点知识——如何判断该树是否为红黑树,或者说改红黑树有没有错误

像书写AVL树一样,在代码的在最后我们也需要一个判断,判断在AVL树中它插入节点后的平衡因子会不会发生异常

同样的红黑树也要这个操作,不同与AVL的是红黑树并没有平衡因子,而它的判断的内容则是红黑树性质的4大规则

这里要判断的就是以上的规则:根节点是否为黑色,是否有两个红节点相连接,它每条路径的黑节点个数是否一样

在了解完了详情之后,接下来就是对代码的书写了。

首先就是进行基础的判断,如果插入后的红黑树它的根节点为空这里就返回true,如果颜色不为黑色,这个地方就返回false

接下来定义一个整形用来存储某条路径黑色节点的个数,这里选择的就是最左路径,统计它最左路径黑色节点的个数

然后上面的代码就跳转到这里,也是一样先看看根节点是否为空,然后再判断里面还需要判断路径的黑色节点数是否相同(递归结束回到根节点处)

如果root处的节点颜色为黑色,这里就对计算黑色节点的整形进行++操作

然后就是if条件判断是否会出现连续的红节点,如果这里的root存在且为红,root的parent存在且为红,这种情况就是出现了连续的红节点,就需要报错后返回false。(这里不能用parent为红,parent的cur节点也为红的条件来判断,因为这里可能存在空节点)

最后这里要递归root节点的左子树与右子树,递归到根节点的parent,回到开头判断各个路径黑色节点的个数是否相同。  

这个地方就是我们的红黑树的判断

代码: 

RBTree.cpp

#include "RBTree.h"int main()
{int a[] = { 16,3,7,11,9 };RBTree<int, int> t;for (auto e : a){t.Insert(make_pair(e, e));cout << "Insert:" << e << "->" << t._IsBalance() << endl;}return 0;
}

RBTree.h 

#pragma once
#include<iostream>
using namespace std;enum Colour
{RED,BLACK
};template<class K,class V>
struct RBTreeNode
{RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;pair<K, V> _kv;Colour _col;RBTreeNode(const pair<K, V>& kv):_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_col(RED){}
};template<class K, class V>
struct 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* cur = _root;Node* parent = nullptr;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);cur->_col = RED;if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;while (parent && parent->_col == RED){Node* grandfather = parent->_parent;if (parent == grandfather->_left){Node* uncle = grandfather->_right;if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED; cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_left){RotateR(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateL(parent);RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else//	if (parent == grandfather->_right){Node* uncle = grandfather->_left;if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}_root->_col = BLACK;return true;}void RotateL(Node* parent){Node* cur = parent->_right;Node* curleft = cur->_left;Node* ppnode = parent->_parent;parent->_right = curleft;if (curleft){curleft->_parent = parent;}cur->_left = parent;parent->_parent = cur;if (parent == _root){_root = cur;cur->_parent = nullptr;}else{if (ppnode->_left == parent){ppnode->_left = cur;}else{ppnode->_right = cur;}cur->_parent = ppnode;}}void RotateR(Node* parent){Node* cur = parent->_left;Node* curright = cur->_right;Node* ppnode = parent->_parent;parent->_left = cur->_right;if (curright){curright->_parent = parent;}cur->_right = parent;parent->_parent = cur;if (ppnode == nullptr){_root = cur;cur->_parent = nullptr;}else{if (ppnode->_left == parent){ppnode->_left = cur;}else{ppnode->_right = cur;}cur->_parent = ppnode;}}bool CheckColour(Node* root, int blacknum, int benchmark){if (root == nullptr){if (blacknum != benchmark){return false;}return true;}if (root->_col == BLACK){++blacknum; }if (root->_col == RED && root->_parent && root->_parent->_col == RED){cout << root->_kv.first << "出现连续红节点" << endl;return false;}return CheckColour(root->_left, blacknum, benchmark) && CheckColour(root->_right, blacknum, benchmark);}bool _IsBalance(){return IsBalance(_root);}bool IsBalance(Node* root){if (root == nullptr){return true;}if (root->_col != BLACK){return false; }int benchmark = 0;Node* cur = _root;while (cur){if (cur->_col == BLACK){++benchmark;}cur = cur->_left;}return CheckColour(root, 0, benchmark);}private:Node* _root = nullptr; 
};

结尾: 

到这里我们的红黑树代码的基本讲解就告一段落了,但是这并不意味着红黑树就结束了,在以后学习的日子中我们会学习然后对红黑树进行封装,如何用AVL树和红黑树去解决一下K,V问题,最后希望这篇博客能给各位带来一些帮助。 

相关文章:

C++——红黑树

作者&#xff1a;几冬雪来 时间&#xff1a;2023年12月7日 内容&#xff1a;C——红黑树讲解 目录 前言&#xff1a; 红黑树的概念&#xff1a; 红黑树的性质&#xff1a; 红黑树的路径计算&#xff1a; 最长路径和最短路径&#xff1a; AVL树与红黑树的区别&#xff…...

【神化世界】asp网页500内部服务器错误的解决方法

问题解决方案记录 一、问题 在asp网页调试的时候&#xff0c;不小心改错了&#xff0c;好好的页面突然出现如下错误信息了&#xff1a; 二、解决方法 终于找到了问题所在&#xff0c;是sql语句出错造成的&#xff0c;特别记录一下。 正确的写法 sql"select * from mem…...

java面试题6

1.什么是Java中的泛型&#xff08;Generic&#xff09;&#xff1f; 答案&#xff1a;泛型是一种参数化类型的机制&#xff0c;在编译时提供类型安全性检查和重用代码的能力。使用泛型可以在编译时检测类型错误&#xff0c;并减少类型转换的需要。 2.Java中的反射&#xff08;…...

(03)vite 处理 css

文章目录 系列全集vite 处理css流程vite如何解决协同开发&#xff0c;样式重复覆盖的问题&#xff1f;使用less通过配置&#xff0c;更改vite的css默认行为vite 利用postcss样式兼容低版本浏览器 系列全集 &#xff08;01&#xff09;vite 从启动服务器开始 &#xff08;02&am…...

阿里云上传文件出现的问题解决(跨域设置)

跨域设置引起的问题 起因&#xff1a;开通对象存储服务后&#xff0c;上传文件限制在5M 大小&#xff0c;无法上传大文件。 1.查看报错信息 2.分析阿里云服务端响应内容 <?xml version"1.0" encoding"UTF-8"?> <Error><Code>Invali…...

利用JavaFX生成验证码图片

以下是一个基于 JavaFX 的验证码图片生成小程序的示例代码: import javafx.application.Application; import javafx.embed.swing.SwingFXUtils; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx…...

6-55.汽车类的继承

根据给定的汽车类vehicle&#xff08;包含的数据成员有车轮个数wheels和车重weight&#xff09;声明&#xff0c;完成其中成员函数的定义&#xff0c;之后再定义其派生类并完成测试。 小车类car是它的派生类&#xff0c;其中包含载人数passenger_load。每个类都有相关数据的输出…...

SCI论文——respectively用法

respectively用于配对两组&#xff08;三组&#xff09;事物&#xff0c;表明后一组与前一组按照相同的顺序排列&#xff0c;从而使句意明确。一般是在句子的最后&#xff0c;而且在respectively的前面需要一个逗号“,” 一 、两组事物&#xff1a; 原则是尽可能靠近第二组的…...

解决方案 | 法大大电子签约加速农牧业数字化进程

近年来&#xff0c;我国农业技术得到快速发展&#xff0c;并开发出一批实用的数字农业技术产品&#xff0c;建立了专用网络数字农业技术平台。数字农业是农业现代化的高级阶段&#xff0c;是创新推动农业农村信息化发展的有效手段&#xff0c;也是我国由农业大国迈向农业强国的…...

设计模式之GoF23介绍

深入探讨设计模式&#xff1a;构建可维护、可扩展的软件架构 一、设计模式的背景1.1 什么是设计模式1.2 设计模式的历史 二、设计模式的分类2.1 创建型模式2.2 结构型模式2.3 行为型模式 三、七大设计原则四、设计模式关系结论 :rocket: :rocket: :rocket: 在软件开发领域&…...

UDP协议实现群聊

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…...

lombok原理 @Slf4j 怎么生成get set log

Lombok是一种Java库&#xff0c;通过注解的方式提供了许多有用的功能&#xff0c;包括生成Getter、Setter、日志等。Slf4j注解是Lombok中的一种&#xff0c;它用于自动生成日志记录器&#xff08;Logger&#xff09;。 下面简要介绍一下Lombok的原理&#xff0c;以及Slf4j注解…...

【目标检测】进行实时检测计数时,在摄像头窗口显示实时计数个数

这里我是用我本地训练的基于yolov8环境的竹签计数模型&#xff0c;在打开摄像头窗口增加了实时计数显示的代码&#xff0c;可以直接运行&#xff0c;大家可以根据此代码进行修改&#xff0c;其底层原理时将检测出来的目标的个数显示了出来。 该项目链接&#xff1a;【目标检测…...

SpringBoot第56讲:SpringBoot集成文件 - 集成EasyExcel之Excel导入导出

集成EasyExcel之Excel导入导出 EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。它能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。它是基于POI来封装实现的,主要解决其易用性,封装性和性能问题。本文是SpringBoot第…...

python3安装lifelines

目录 一、环境 二、安装lifelines 出现问题 三、测试导入 一、环境&#xff1a; jupyter notebook中新建ipynb文件 二、安装lifelines pip install --upgrade --no-deps githttps://github.com/CamDavidsonPilon/lifelines.git出现问题&#xff1a; 缺少模块autograd、f…...

shell命令学习(1)——(待完善)

explainshell.com shell统计当前文件夹下的文件个数、目录个数Linux之shell常用命令&#xff08;三&#xff09; sort&#xff08;排序&#xff09;、uniq&#xff08;处理重复字符&#xff09; linux中shell将换行输入到文件中 shell脚本&#xff0c;将多行内容写入文件中 f…...

机器的深度强化学习算法可以被诱导

设计一个好的奖励函数是机器深度强化学习算法的关键之一。奖励函数用于给予智能体&#xff08;机器&#xff09;在环境中采取不同行动时的反馈信号&#xff0c;以指导其学习过程。一个好的奖励函数应该能够引导智能体朝着期望的行为方向学习&#xff0c;并尽量避免潜在的问题&a…...

学生成绩管理系统(Java)

开发环境: Windows 11 IDEA 2021.3.3 需求: package com.it.neu;import java.util.ArrayList; import java.util.Scanner;import static java.time.Clock.system;class Student { //创建学生类private String Stu_name;private String Stu_id;public Student(String id, S…...

Modbus数据采集模块是什么?

随着工业自动化的快速发展&#xff0c;数据采集已成为现代工厂不可或缺的一环。在众多通信协议中&#xff0c;Modbus因其开放、简单、可靠的特点而广受青睐。那么&#xff0c;什么是Modbus数据采集模块&#xff0c;它又有哪些应用呢&#xff1f; 一、什么是Modbus数据采集模块…...

【网络安全】下载并安装 kali 的虚拟机 版本

kali虚拟机版本的下载地址&#xff1a;Get Kali | Kali Linux 下载完成后&#xff0c;解压&#xff0c;双击.vmx打开&#xff0c;即可完成kali在虚拟机中的安装和配置。 默认账户和密码都为kali...

JREBEL 热部署原理

JRebel&#xff08;Java Rebel&#xff09;是一个Java开发工具&#xff0c;它提供了一种在不重启应用服务器的情况下进行Java应用程序的热部署的方式。通过JRebel&#xff0c;开发者可以在修改Java代码后立即看到变化&#xff0c;加速开发和调试过程。 以下是JRebel实现热部署…...

履带吊,笔记

0.前言 履带吊使用了与传统的门桥式起重机不同的技术路线。因为它是移动式设备&#xff0c;所以它的动力是燃油发动机。为了精确调控升降。它的整套动力系统似乎采用了某种液压传动系统。履带吊国内也有生产商。但是下文中&#xff0c;还是从国外的一款产品说起。这款产品的pd…...

WPF转换器Convert

图像名称转换器ImageNameConverter&#xff0c;用于在数据绑定中将图像路径转换为图像文件名。 转换器的代码如下&#xff1a; using System; using System.Globalization; using System.IO; using System.Windows.Data;namespace ImageConverter {public class ImageNameCon…...

【刷题】【力扣牛客】反转链表的五种方式——Java

文章目录 前言方法一&#xff1a;构造新链表&#xff08;构造新节点&#xff09;方法二&#xff1a;构造新链表&#xff08;不构造新节点&#xff09;方法三&#xff1a;递归方法四&#xff1a;双指针方法五&#xff1a;遍历总结 力扣题目链接&#xff1a;206. 反转链表 牛客题…...

使用Java网络编程,窗口,线程,IO,内部类等实现多人在线聊天1.0

1.整体思路 思路图 整体思路如上: 涉及知识点:线程网络编程集合IO等 TCP 协议 2.代码实现过程 服务端 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import jav…...

相关教程test

第一天 主题&#xff1a;LLM初体验 上午&#xff1a; 一&#xff0c;大模型的发展背景和模型演进 数据增长和算力提升LSTM到BERT到LLM的参数巨变最新paper解读&#xff08;根据授课时间&#xff0c;选择最近的核心paper进行解读&#xff09; 二&#xff0c;大模型核心阶段…...

mysql知识分享(包含安装卸载)(一)

如果博客有错误&#xff0c;请佬指正。 目录 注意&#xff1a;打开cmd时要有管理员身份打开&#xff0c;重要 为何使用数据库&#xff1f; 数据库的相关概念 关系型数据库 关系型数据库设计规则 表&#xff0c;记录&#xff0c;字段 表的关联关系 一对一关联 一对多关系 …...

Google Guava 反射工具使用详解

文章目录 反射类操作方法操作字段操作获取注解 反射 在 Guava 中&#xff0c;反射&#xff08;Reflection&#xff09;模块提供了一些用于简化反射操作的工具类和方法。通过 Guava 的反射模块&#xff0c;您可以方便地进行类、方法、字段的操作、获取注解信息等。下面详细介绍…...

MySql MVCC 详解

注意以下操作都是以InnoDB引擎为操作基准。 一&#xff0c;前置知识准备 1&#xff0c;MVCC简介 MVCC 是多版本并发控制&#xff08;Multiversion Concurrency Control&#xff09;的缩写。它是一种数据库事务管理技术&#xff0c;用于解决并发访问数据库的问题。MVCC 通过创…...

工业机器视觉megauging(向光有光)使用说明书(三,轻量级的visionpro)

下来我们说说第二个相机的添加&#xff1a; 第一步&#xff0c;点击相机二&#xff0c;如下&#xff1a; 第二步&#xff0c;点击&#xff1a;加载工具组.xml&#xff0c;加载toolgroupxml2目录下的&#xff1a;工具组.xml 注意&#xff0c;一个相机只能用一个toolgroupxml,第…...

Linux 环境下,jdbc连接mysql问题

1. 下载MySQL的JDBC驱动&#xff1a; 从MySQL官网下载最新的MySQL Connector/J&#xff0c;并将其解压到某个目录&#xff0c;比如/usr/local/mysql/。 2. 将JDBC驱动添加到类路径&#xff1a; 将JDBC驱动添加到类路径&#xff0c;可以使用以下命令&#xff1a; export CLA…...

Python读写txt文件数据

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;如喜欢麻烦您点个&#x1f44d;或者点个⭐&#xff01; &#x1f…...

Linux虚假唤醒

为什么会有虚假唤醒一说。Linux内核这么强大&#xff0c;怎么会出现这样的情况&#xff1f;一直以来也很困惑&#xff0c;看了下文链接中的介绍后&#xff0c;豁然开朗。 从计算机设计的角度&#xff0c;如果一层解决不了&#xff0c;那就再多加一层。推算到这里&#xff0c;就…...

倒计时模块复习

经典回顾倒计时 倒计时的基本布局介绍。 一个内容区域和一个输入区域&#xff0c;内容区域进行划分 直接使用flex布局会更快一点。 js代码 我们利用一下模块化思想&#xff0c;直接把获得时间这个功能写成一个函数。方便后续的调用 function getTime() {const date new Date…...

k8s(三): 基本概念-ReplicaSet与Deployment

PeplicaSet ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合&#xff0c;通常用来保证给定数量的、完全相同的 Pod 的可用性。 最佳实践 Deployment 是一个可以拥有 ReplicaSet 并使用声明式方式在服务器端完成对 Pod 滚动更新的对象。 尽管 Rep…...

Linux 的介绍和云服务器上web 程序部署

目录 一.linux的介绍 1.1linux是什么 1.2linux的发展历程 1.3linux发行版 二.Linux环境搭建 2.1阿里云-云服务器配置 2.2使用终端软件连接Linux 三.操作Linux&#xff0c;部署web程序 3.1Linux指令 3.2部署web程序 第一步&#xff1a;认识yum 第二步&#xff1a;安装…...

Oauth2.0 学习

OAuth 2.0 服务器端通常通过验证每次请求中的访问令牌&#xff08;access token&#xff09;的方式来确保其合法性和有效性。以下是一些通常采用的验证方法&#xff1a; Token Validation Endpoint: OAuth 2.0 规范允许实现一个专门的令牌验证端点&#xff0c;称为 Token Valid…...

Elasticsearch:什么是向量数据库?

向量数据库定义 向量数据库是将信息存储为向量的数据库&#xff0c;向量是数据对象的数值表示&#xff0c;也称为向量嵌入。 它利用这些向量嵌入的强大功能来对非结构化数据和半结构化数据&#xff08;例如图像、文本或传感器数据&#xff09;的海量数据集进行索引和搜索。 向…...

rename--统一的PRF

基本概念 将ARF/PRF进行合并&#xff0c;合同之后的不见&#xff0c;称之为统一的PRF(Physical Register File);存储的是speculative的&#xff0c;以及正确的&#xff08;retire&#xff09;寄存器值&#xff1b; 使用free list&#xff0c;存储PRF中&#xff0c;哪些寄存器是…...

010-editor破解(1)

查看字符串 使用rabin2 -z /home/burning/010editor/010editor | tee 22.txt 查看字符串。 6698 0x003ba380 0x007ba380 68 69 .rodata ascii The password you entered is for an earlier version of this program. 6699 0x003ba3c8 0x007ba3c8 70 71 .rodata ascii You will…...

Ubuntur编译ROS报错:error PCL requires C++14 or above

ubuntu20.04 编译ROS包 报错&#xff1a; error&#xff1a; PCL requires C14 or above&#xff1a; 修改Cmakelists.txt文件&#xff1a; set&#xff08;CMAKE_CXX_STANDARD 14&#xff09; 再次编译成功....

17.认识下Docker之docker的核心原理(2)

1.容器-我的小世界 不知道大家看没看过小说《完美时间》&#xff0c;里面石昊经常进入一个小世界在里面与世隔绝的修炼或者战斗&#xff0c;总之就是在一个完全封闭的空间里做他想做的事情而与外界隔离&#xff0c;不受侵扰。通过前面的分析我们知道&#xff0c;Namepace让应用…...

【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)

文章目录 前言正文一、POM依赖二、核心Java文件2.1 自定义表头注解 ExcelColumnTitle2.2 自定义标题头的映射接口2.3 自定义有序map存储表内数据2.4 表头工厂2.5 表flag和表头映射枚举2.6 测试用的实体2.6.1 NameAndFactoryDemo2.6.2 StudentDemo 2.7 启动类2.8 测试控制器 三、…...

代码随想录算法训练营第四十二天 _ 动态规划_01背包问题、416.分割等和子集。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 二维数组处理01背包问题 听起来…...

市场上好用的aspera替代方案,你知道哪些

Aspera作为一个高速文件传输方案曾经非常受欢迎&#xff0c;但是其昂贵的价格却限制了许多用户的选择&#xff0c;因此市场上出现了众多Aspera替代方案&#xff0c;本文将会介绍市场上最好的Aspera替代方案。 最近几年&#xff0c;网络传输已成为现代商业运作中必不可少的一部…...

Stm32_串口的帧(不定长)数据接收

目录标题 前言1、串口中断接收固定帧头帧尾数据1.1、任务需求1.2、实现思路1.3、程序源码&#xff1a; 2、串口中断接收用定时器来判断帧结束3、串口中断接收数据空闲中断3.1、串口的空闲中断3.2、实现思路3.3、程序源码 4、串口的空闲中断DMA转运4.1、DMA简介4.2、DMA模式4.3、…...

L0、Linux常用命令

一、防火墙&#xff1a; 在 Linux 中&#xff0c;关闭防火墙可以使用不同的命令&#xff0c;这取决于你所使用的防火墙软件。在一些常见的 Linux 发行版中&#xff0c;防火墙可能是 iptables 或 firewalld两种&#xff1a; centos6使用iptables作为默认防火墙&#xff1b;cento…...

Golang实践录:读取toml配置

本文对 toml 文件进行解析。 下载 对于toml格式文件&#xff0c;golang 有很多库可以解释 yaml 文件&#xff0c;如toml、viper。由于 viper 可解析格式较多&#xff0c;本文采用该库。 toml语法规则 toml语法规则在官方中文文档上有说明&#xff0c;这里直接使用。 TOML 是…...

超大规模集成电路设计----基于阵列的可编程逻辑(七)

本文仅供学习&#xff0c;不作任何商业用途&#xff0c;严禁转载。本篇文章绝大部分资料来自中国科学院段成华教授PPT 超大规模集成电路设计----基于阵列的可编程逻辑&#xff08;七&#xff09; 7.1 引言7.1.1.回顾7.1.2. 数字逻辑系列Digital Logic Families7.1.3.从定制到半…...

深入探索FastAPI单元测试:使用TestClient轻松测试你的API

原文&#xff1a;深入探索FastAPI单元测试&#xff1a;使用TestClient轻松测试你的API-51CTO.COM 当使用FastAPI进行单元测试时&#xff0c;一个重要的工具是TestClient类。TestClient类允许我们模拟对FastAPI应用程序的HTTP请求&#xff0c;并测试应用程序的响应。这使我们能…...