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

红黑树和 STL —— set和map 【复习笔记】

1. 二叉搜索树

1.1 二叉搜索树的概念

相比较前文的堆,二叉搜索树并不需要必须是一棵完全二叉树

二叉搜索树(二叉排序树或二叉查找树,简称BST)是具有以下特性的二叉树:

1. 若它的左子树非空,则左子树上所有结点的值均小于它的根结点的值。

2. 若它的右子树非空,则右子树上所有结点的值均大于它的根结点的值。

3. 它的左、右子树也分别为二叉搜索树。

即左子树结点的值 < 根结点的值 < 右子树结点值(在二叉搜索树中,一般不存在值相同的两个结点)

所以,对二叉搜索树中序遍历,可以得到一个递增的有序序列

1.2 二叉搜索树的查找、插入和删除

查找

二叉搜索树查找从根节点开始,逐层向下比较,先让给出的值与根结点比较,如果相等,就结束;如果小于根结点,就在根结点的左子树上查找;如果大于根结点,就在根结点的右子树上查找。递归进行,直到查找到叶子结点

因为查找是逐层的,所以查找的时间复杂度一般是O(log N),但是,树高最差会没有分支,变成2单链表,考虑最坏情况,所以时间复杂度为O(N)

插入

二叉搜索树的插入操作要以查找操作为基础,查找过程中,树不存在给定的值时再插入,插入的结点一定是新的叶结点(查找失败时访问的最后一个结点的左孩子或右孩子)

因为插入和查找相绑定,所以时间复杂度为O(N)

对于插入,如果二叉搜索树为空树,要插入是所有结点的值都相同,插入顺序不同所构造的二叉搜索树也不同

删除

二叉搜索树的删除操作也要以查找操作为基础,但对于删除操作,可能删除某个结点后,这棵树就不满足二叉搜索树的特性,所以删除有多种情况:

1.  删除的结点是叶子结点,直接删除

2. 删除的结点 m 只有一棵左子树或右子树,则让 m 的子树成为 m 父结点的子树,替代 m

3. 删除的结点 m 的左右子树都存在,有两种方法:

   3.1 让 m 的直接后继(m 的右子树中最小的结点)替代 m ,然后删除这个直接后继

   3.2 让 m 的直接前驱( m 的左子树中最大的结点)替代 m ,然后删除这个直接前驱

对于直接前驱直接后继 :

将二叉搜索树中序遍历,会得到一个递增的有序序列。而 m 的直接后继,就是这个序列中 m 的后继,在树中就是 m 的右子树最左下的结点(该结点无左子树);m 的直接前驱,就是这个序列中 m 的前驱,在树中就是 m 的左子树最右下的结点(该结点无右子树)

而之后的删除直接前驱或直接后继,因为无右子树或无左子树,可以按照方法 1,2 进行删除

2. 平衡二叉树

2.1 平衡二叉树的概念

因为二叉搜索树在某些情况下会没有分支,退化为单链表,所以我们需要一些方法维持二叉搜索树的“ 平衡 “,而使用下面方法维持平衡的,就是平衡二叉树,平衡二叉树就是一种特殊的二叉搜索树(具有二叉搜索树的性质)

规定在插入和删除结点时,保证任意结点的左、右子树的高度差的绝对值不超过 1 ,这样的二叉搜索树被称为平衡二叉树(AVL树)

平衡因子:结点的左子树和右子树的高度差,平衡二叉树中每一个结点的平衡因子只可能是 -1、0、1

2.2 查找

和二叉搜索树的查找一样:从根节点开始,逐层向下比较,先让给出的值与根结点比较,如果相等,就结束;如果小于根结点,就在根结点的左子树上查找;如果大于根结点,就在根结点的右子树上查找。递归进行,直到查找到叶子结点

时间复杂度:因为平衡二叉树限制子树的树高差,所以不会出现二叉搜索树那样极端的情况,因此时间复杂度为 O(log N)

2.3 插入

2.3.1 插入的背景

先按照二叉搜索树的方法进行插入,但插入结点后,可能改变了左右子树的树高差,让平衡因子的绝对值大于 1 ,所以需要再调整这棵树的结构。

在调整结构前,我们要知道一个概念:最小不平衡子树

最小不平衡子树:在平衡二叉树中,以离插入节点最近且平衡因子绝对值大于 1 的节点为根的子树。( 当对平衡二叉树进行插入操作时,可能会导致树的平衡性被破坏,从插入节点开始向上查找,第一个出现平衡因子绝对值大于 1 的节点所对应的子树就是最小不平衡子树 )

对于插入操作,仅需调整最小不平衡子树,就可以让所以结点平衡:

这棵树原来就是平衡二叉树,如果插入一个结点后失衡,那失衡的平衡因子的绝对值只能是2

当最小平衡子树调整平衡后,这棵子树的高度减1,向上传递,就让整个路径的平衡因子向下靠近,树就平衡了

对于插入操作的时间复杂度:后续的调整仅需修改指针,所以最大的时间开销和查找一样,所以时间复杂度为O(log N)

2.3.2 插入的方法

最小不平衡子树的出现分为 4 种情况,所以调整方法也有 4 种情况(下面情况假设最小不平衡子树的根结点为 T,左孩子为 L,右孩子为 R,左孩子的右孩子为 LR,右孩子的左孩子为 RL)

2.3.2.1 LL型 - 右单旋

LL型:新结点插入到 T 结点的左孩子(L)的左子树(L)中,导致失衡

右单旋:将结点 T 以左孩子 L 为轴向右下旋转作为结点 L 的右子树的根结点

              结点 L 的原右子树则作为结点 T 的左子树

              结点 L 就代替 T 成为根节点

2.3.2.2 RR型 - 左单旋

RR型:新结点插入到 T 结点的右孩子 (R) 的右子树(R)中,导致失衡

左单旋:将结点 T 以右孩子 R 为轴向左下旋转作为结点 R 的左子树的根结点

              结点 R 的原左子树则作为结点 T 的右子树

              结点 R 就代替 T 成为根结点

2.3.2.3 LR型 - 左右双旋

左右双旋分为两步,先左旋,再右旋

LR型:新结点插入到 T 结点的左孩子(L)的右子树(R)中,导致失衡

左旋:将结点 L 以 LR 为轴向左下旋转作为 LR 的左子树的根节点

           结点 LR 的原左子树则作为结点 L 的右子树

           结点 LR 就替代 L 成为根结点

右旋:将结点 T 以 LR 为轴向右下旋转作为结点 LR 的右子树的根结点

           结点 LR 的原右子树则作为结点 T 的左子树

           结点 LR 就替代 T 成为根结点

2.3.2.4 RL型 - 右左双旋

右左双旋分为量步,先右旋,再左旋

RL型:新结点插入到 T 结点的右孩子(R)的左子树(L)中,导致失衡

右旋:将结点 R 以 RL 为轴向右下旋转作为 RL 的右子树的根结点

           结点 RL 的原右子树则作为结点 R 的右子树

           结点 RL 就替代 R 成为根结点

左旋:将结点 T 以 RL 为轴向左下旋转作为 RL 的左子树的根结点

           结点 RL 的原左子树则作为结点 T 的右子树

           结点 RL 就替代 T 成为根结点

2.4 删除

删除操作和二叉搜索树的删除操作相似,删除后的调整思想和插入操作后的调整思想相似,时间复杂度为O(log N)

步骤:

1. 用二叉搜索树的删除方法对结点 e 进行删除

2. 从结点 e 开始,向上找到最小不平衡子树(假设第一个不平衡结点为 T ,结点 T 的高度最高的孩子结点为 X,结点 X 的高度最高的孩子结点为 Y)

3. 对以 Y 为根的子树进行平衡调整,根据 Y、X、T的位置可同插入操作一样分为 4 种情况:

         a.  LL型 - 右单旋:X 是 T 的左孩子(L),Y 是 X 的左孩子(L)

         b.  RR型 - 左单旋:X 是 T 的右孩子(R),Y 是 X 的右孩子(R) 

         c.  LR型 - 左右双旋:X 是 T 的左孩子(L),Y 是 X 的右孩子(R)

         d.  RL型 - 右左双旋:X 是 T 的右孩子(R),Y 是 X 的左孩子(L) 

4. 调整之后,继续向上找下一个最小不平衡子树,重复 3 操作,直到找不到为止

( 因为删除操作不像插入操作一样,删除操作可能导致大量结点失衡,一次调整不能保证整棵树的结点是平衡的。所以需要不断调整,重复 3 过程)

3. 红黑树

3.1 红黑树的概念和性质

红黑树(简称RBT)也是一个二叉搜索树,它具有二叉搜索树的特性。它在二叉搜索树的基础上,让它的每个节点都有一个颜色属性,可以是红色或黑色。通过下面的各个结点的着色规则限制,确保没有一条路径会比其他路径长出 2 倍,所以红黑树是一棵接近平衡的二叉搜索树

着色规则:

1. 每个结点是红色或黑色

2. 根结点和叶子节点(这里的叶子结点不是常规树上的叶子结点,而是空结点(NULL)是黑色

3.每个红色结点的两个子结点都是黑色(任意一条路径上不会有连续的红色结点)

4. 任意一个结点,从该结点到其所有叶子结点的路径上,均包含相同数目的黑色结点

由于红黑树的着色规则,我们可以得到它的两个重要性质

1. 从根结点到叶子结点的最长路径不会大于最短路径的 2 倍

2. 有 n 个结点的红黑树,高度 h <= 2log(n+1),即查找的时间复杂度为O(log N)

3.2 查找

红黑树的查找和二叉搜索树的查找一样:从根节点开始,逐层向下比较,先让给出的值与根结点比较,如果相等,就结束;如果小于根结点,就在根结点的左子树上查找;如果大于根结点,就在根结点的右子树上查找。递归进行,直到查找到叶子结点

时间复杂度为O(log N)

3.3 插入

3.3.1 插入步骤

1. 先按照二叉搜索树的插入方式进行插入,新插入的结点默认为红色

( 如果默认黑色,那么这条路径的黑色结点增多,要调整所有从根节点到叶子结点的路径,让树重新符合红黑树的特性。调整规模过于庞大

如果默认红色,那么只会破坏根结点不能为红色不能出现连续的红色结点的规则,调整起来相对简单 )

2. 如果新插入结点破坏红黑树的规则,那么要分情况调整

3.3.2 调整方法

假设新插入的结点为 c(cur),父结点为 p(parent),父结点的父结点为 g(grandfather),父结点的兄弟结点为 u (uncle)

3.3.2.1 插入的是根结点

直接将结点颜色变为黑色

3.3.2.2 插入节点的叔叔结点是红色

父亲、叔叔、爷爷结点同时变色,将爷爷结点看成新插入的结点,继续向上判断

( p、u 变为黑色,g 变成红色,整个路径的黑色结点数目保持平衡,数量不变;但 g 变成红色,可能 g 是根结点,或 g 的父亲结点也是红色,违反规则,所以将 g 当成插入结点重新判断)

3.3.2.3 插入节点的叔叔结点是黑色

这种情况要分类讨论,根据插入结点、父结点和爷爷结点的位置旋转+变色

3.3.2.3.1 LL型 - 右单旋 + 父爷变色

LL型:新结点为 g 结点的左孩子 p (L)的左孩子(L)

1. 右旋父亲结点(将爷爷结点以父亲结点为轴向右下旋转)

2. 将父亲结点和爷爷结点进行变色

3.3.2.3.2 RR型 - 左单旋 + 父爷变色

RR型:新结点为 g 结点的右孩子 p(R)的右孩子(R)

1. 左旋父亲结点(将爷爷结点以父亲结点为轴向左下旋转)

2. 将父亲结点和爷爷结点进行变色

3.3.2.3.3 LR型 - 左右双旋 + 儿爷变色

LR型:新结点为 g 结点的左孩子 p(L)的右孩子(R)

1. 新结点先左旋,再右旋(先将 p 结点以新结点为轴向左下旋转,新结点代替 p 结点的位置;再将 g 结点以新结点为轴向右下旋转)

2. 将新结点和爷爷结点进行变色

3.3.2.3.4 RL型 - 右左双旋 + 儿爷变色

RL型:新结点为 g 结点的右孩子 p(R)的左孩子(L)

1. 新结点先右旋,再左旋(先将 p 结点以新结点为轴向右下旋转,新结点代替 p 结点的位置,再将 g 结点以新结点为轴向左下旋转)

2. 将新结点和爷爷结点进行变色

3.4 删除

删除操作较复杂,为控制篇幅,之后篇章再讨论

4. STL —— set和map

4.1 set/multiset

set 和 multiset 的区别:set 不能存相同元素,multiset 可以存相同元素,其他的使用方法完全一致

所以set可以用来给数据去重

#include<iostream>
#include<set>
using namespace std;void test()
{set<int> mp;//insert:插入元素,时间复杂度O(log N)for (int i = 5; i >= 1; i--){mp.insert(i);}//begin/end,返回迭代器,可以用范围 for 遍历整个红黑树//中序遍历 set,结果应该递增有序for (auto x : mp){cout << x << " ";}cout << endl;//size:返回 set 中元素个数,时间复杂度O(1)cout << mp.size() << endl;//empty:判断 set 是否为空,时间复杂度O(1)if (!mp.empty()) cout << "非空" << endl;//erase:删除元素,时间复杂度O(log N)mp.erase(5);mp.erase(4);for (auto x : mp){cout << x << " ";}cout << endl;//find:查找一个元素,返回迭代器,时间复杂度O(log N)//cout:查询元素出现的次数,一般用来判断元素是否在红黑树中,时间复杂度O(log N)//想查找元素是否在set中,我们一般使用count,而非find,因为find返回迭代器不方便使用if (mp.count(1)) cout << "1" << endl;if (mp.count(5)) cout << "5" << endl;//lower_bound:大于等于变量的最小元素,返回迭代器//upper_bound:大于变量的最小元素,返回迭代器//时间复杂度都为O(log N)auto x = mp.lower_bound(1);auto y = mp.upper_bound(1);cout << *x << " " << *y << endl;return;
}int main()
{test();return 0;
}

4.2 map/multimap

map 和 multimap 的区别:map 不能存相同的元素,multimap 可以存相同的元素,其他的使用方法完全一致

map 和 set 的区别:set 里存储一个单独的关键字;而 map 里面存一个 pair<key,value>(k-v模型),除了一个关键字,还有一个和关键字绑定的值,但比较是以 key 进行的

比如:<int,int>,可以统计数字出现的次数

          <string,int>可以统计字符串出现的次数

#include<iostream>
using namespace std;
#include<map>void print(map<string, int>& mp)
{//begin/end:返回迭代器,可以用范围for遍历整个 mapfor (auto& p : mp){cout << p.first << " " << p.second << endl;}
}void test()
{map<string, int> mp;//insert:插入元素,要插入一个pair,时间复杂度O(log N)mp.insert({ "lili",1 });mp.insert({ "kiki",2 });print(mp);//operator[]可以让 map 像数组一样使用cout << mp["lili"] << endl;mp["lili"] = 3;cout << mp["lili"] << endl;//但operator[]可能会向 map 插入意料外的元素//插入时,第一个关键字为[]里内容,第二个关键字为默认值if (mp["wiwi"] == 3) cout << mp["wiwi"] << endl;//可以发现本不想插入wiwi,只是比较一下,但插入进去了print(mp);//erase:删除,时间复杂度O(log N)mp.erase("wiwi");//find:查询一个元素,返回迭代器//count:查询元素出现的次数,可以判断该元素是否在map中//时间复杂度都是O(log N),一般使用count查询元素if (mp.count("wiwi") && mp["wiwi"] == 0) cout << "yes" << endl;print(mp);//size:求map的大小,时间复杂度O(1)//empty:判断map是否为空,时间复杂度O(1)cout << mp.size() << endl;if (!mp.empty()) cout << "非空" << endl;//lower_bound:大于等于传入值的最小元素,返回迭代器//upper_bound:大于传入值的最小元素,返回迭代器//时间复杂度都是O(log N)auto x = mp.lower_bound("kiki");auto y = mp.upper_bound("kiki");cout << (*x).first << " " << (*y).first << endl;}int main()
{test();return 0;
}

相关文章:

红黑树和 STL —— set和map 【复习笔记】

1. 二叉搜索树 1.1 二叉搜索树的概念 相比较前文的堆&#xff0c;二叉搜索树并不需要必须是一棵完全二叉树 二叉搜索树&#xff08;二叉排序树或二叉查找树&#xff0c;简称BST&#xff09;是具有以下特性的二叉树&#xff1a; 1. 若它的左子树非空&#xff0c;则左子树上所…...

网络空间安全(7)攻防环境搭建

一、搭建前的准备 硬件资源&#xff1a;至少需要两台计算机&#xff0c;一台作为攻击机&#xff0c;用于执行攻击操作&#xff1b;另一台作为靶机&#xff0c;作为被攻击的目标。 软件资源&#xff1a; 操作系统&#xff1a;如Windows、Linux等&#xff0c;用于安装在攻击机和…...

HarmonyOS学习第11天:布局秘籍RelativeLayout进阶之路

布局基础&#xff1a;RelativeLayout 初印象 在 HarmonyOS 的界面开发中&#xff0c;布局是构建用户界面的关键环节&#xff0c;它决定了各个组件在屏幕上的位置和排列方式。而 RelativeLayout&#xff08;相对布局&#xff09;则是其中一种功能强大且灵活的布局方式&#xff0…...

【2025年2月28日稳定版】小米路由器4C刷机Immortalwrt 23.05.4系统搭载mentohust 0.3.1插件全记录

小米路由器4C刷机Immortalwrt系统搭载mentohust插件全记录 首先将路由器按住后面的reset&#xff0c;用一个针插进去然后等待5s左右&#xff0c;松开&#xff0c;即可重置路由器。 然后要用物理网线物理连接路由器Lan口和电脑&#xff0c;并将路由器WAN口连接至网口。确保电脑…...

【SpringBoot+Vue】博客项目开发二:用户登录注册模块

后端用户模块开发 制定参数交互约束 当前&#xff0c;我们使用MybatisX工具快速生成的代码中&#xff0c;包含了一个实体类&#xff0c;这个类中包含我们数据表中的所有字段。 但因为有些字段&#xff0c;是不应该返回到前端的&#xff0c;比如用户密码&#xff0c;或者前端传…...

idea + Docker + 阿里镜像服务打包部署

一、下载docker desktop软件 官网下载docker desktop&#xff0c;需要结合wsl使用 启动成功的画面(如果不是这个画面例如一直处理start或者是stop需要重新启动&#xff0c;不行就重启电脑) 打包成功的镜像在这里&#xff0c;如果频繁打包会导致磁盘空间被占满&#xff0c;需…...

从入门到精通:Linux 权限管理(rwx/chmod/chown)

目录 1. 引言&#xff1a;为什么需要文件权限&#xff1f; 2. 基础概念&#xff1a;理解 rwx 权限 &#xff08;1&#xff09;权限的三种角色 &#xff08;2&#xff09;权限的三种类型 &#xff08;3&#xff09;权限的两种表示法 &#xff08;4&#xff09; 目录的 rwx…...

虚拟机如何设置ip

在虚拟机中设置IP地址的具体步骤会因虚拟机软件&#xff08;如VMware、VirtualBox等&#xff09;和操作系统&#xff08;如Windows、Linux等&#xff09;的不同而有所差异。以下是几种常见虚拟机软件和操作系统的IP设置方法。 --- 一、VMware中的IP设置 1.Windows虚拟机 1. 打…...

自然语言处理:稀疏向量表示

介绍 大家好&#xff0c;我是博主。今天又来和大家分享自然语言处理领域的知识了。原本我计划这次分享NLP中文本表示的相关内容&#xff0c;不过在整理分享计划的过程中&#xff0c;发现这部分知识里包含一些涉及复杂数学原理和抽象概念的内容。对于刚接触NLP的小伙伴们来说&a…...

ubuntu 20.04 安装labelmg

1. 下载安装包 下载链接&#xff1a;下载链接 2. 安装启动 # 创建labelImg的环境 conda create -n labelImg# 激活labelImg环境 source activate labelImg安装依赖 pip install pyqt5-dev-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/cd requirements/pip install -…...

Redis版本的EOL策略与升级路径(刷到别划走)

各位看官&#xff0c;刷到就点进来&#xff0c;大数据已经抓到你喽&#xff5e;&#x1f60a; 前言 在软件行业做服务端开发的我们&#xff0c;多多少少都会接触到Redis&#xff0c;用它来缓存数据、实现分布式锁等&#xff0c;相关八股文烂熟于心&#xff0c;但是往往会忽略具…...

ExpMoveFreeHandles函数分析和备用空闲表的关系

第一部分&#xff1a;ExpMoveFreeHandles和备用空闲表的关系 ULONG ExpMoveFreeHandles ( IN PHANDLE_TABLE HandleTable ) { ULONG OldValue, NewValue; ULONG Index, OldIndex, NewIndex, FreeSize; PHANDLE_TABLE_ENTRY Entry, FirstEntry; EXHAND…...

[预订酒店]

预订酒店 真题目录: 点击去查看 E 卷 100分题型 题目描述 放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为n的数组A),他的心理价位是x元,请帮他筛选出k个最接近x元的酒店(n>=k>0),并由低到高打印酒店的价格。 输入描述 第一行:n,…...

java项目之基于ssm的学籍管理系统(源码+文档)

项目简介 基于ssm的学籍管理系统实现了以下功能&#xff1a; 学生信息管理&#xff1a; 学生信息新增 学生信息修改 学籍异动管理&#xff1a; 学籍异动添加 学籍异动删除 学籍异动修改 学生学业管理&#xff1a; 学生学业添加 学生学业修改 学生学业删除 学院信息管理&am…...

SpringBoot+Redis+Mybatis-plus黑马点评

短信登录 基于Session实现登录 流程&#xff1a; 发送短信验证码-->短信验证码注册登录-->校验登录状态&#xff08;保存用户到ThreadLocal&#xff0c;方便后续使用&#xff09; 不能每次请求服务都要进行登录状态校验&#xff0c;解决办法&#xff1a;拦截器 在Sp…...

算法-二叉树篇23-二叉搜索树中的插入操作

二叉搜索树中的插入操作 力扣题目链接 题目描述 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同…...

[STM32]从零开始的STM32 BSRR、BRR、ODR寄存器讲解

一、前言 学习STM32一阵子以后&#xff0c;相信大家对STM32 GPIO的控制也有一定的了解了。之前在STM32 LED的教程中也教了大家如何使用寄存器以及库函数控制STM32的引脚从而点亮一个LED&#xff0c;之前的寄存器只是作为一个引入&#xff0c;并没有深层次的讲解&#xff0c;在教…...

DeepSeek-V3关键技术之一:DeepSeekMoE

DeepSeekMoE 是一种创新的大规模语言模型架构&#xff0c;旨在通过高效的计算流程和优化设计&#xff0c;在保持高性能的同时显著降低计算成本。 1. 架构设计 DeepSeekMoE 基于 Transformer 架构&#xff0c;融合了以下核心技术&#xff1a; 专家混合系统&#xff08;Mixture…...

MySQL--DQL、DML、DDL、DCL概念与区别

在SQL中&#xff0c;根据功能和操作对象的不同&#xff0c;通常将语文分为四大类&#xff1a;DQL&#xff08;数据查询语言&#xff09;、DML&#xff08;数据操作语言&#xff09;、DDL&#xff08;数据定义语言&#xff09;、DCL&#xff08;数据控制语言&#xff09; 一、D…...

Android Activity启动流程详解

目录 Activity 启动流程详细解析 1. 应用层发起启动请求 1.1 调用 startActivity() 1.2 通过 Instrumentation 转发请求 2. 系统服务处理&#xff08;AMS 阶段&#xff09; 2.1 Binder IPC 通信 2.2 AMS 处理流程 2.3 跨进程回调 ApplicationThread 3. 目标进程初始化…...

夜天之书 #106 Apache 软件基金会如何投票选举?

近期若干开源组织进行换届选举。在此期间&#xff0c;拥有投票权的成员往往会热烈讨论&#xff0c;提名新成员候选人和治理团队的候选人。虽然讨论是容易进行的&#xff0c;但是实际的投票流程和运作方式&#xff0c;在一个成员众多的组织中&#xff0c;可能会有不少成员并不清…...

保姆级教程:用Chart.js实现柱状图与折线图联动

保姆级教程:用Chart.js实现柱状图与折线图联动 ▲ 最终实现的交互式组合图表效果 一、技术原理剖析 1.1 Chart.js渲染机制 Chart.js基于HTML5 Canvas实现图表绘制,其核心原理包括: 数据绑定:将数据对象映射为图形元素分层渲染:通过order属性控制图层叠加顺序坐标系计算:…...

初阶MySQL(两万字全面解析)

文章目录 1.初识MySQL1.1数据库1.2查看数据库1.3创建数据库1.4字符集编码和排序规则1.5修改数据库1.6删除数据库 2.MySQL常用数据类型和表的操作2.(一)常用数据类型1.数值类2.字符串类型3.二进制类型4.日期类型 2.(二)表的操作1查看指定库中所有表2.创建表 3.查看表结构和查看表…...

大模型应用:多轮对话(prompt工程)

概述 在与大型语言模型&#xff08;如ChatGPT&#xff09;交互的过程中&#xff0c;我们常常体验到与智能助手进行连贯多轮对话的便利性。那么&#xff0c;当我们开启一个新的聊天时&#xff0c;系统是如何管理聊天上下文的呢&#xff1f; 一、初始上下文的建立 1. 创建新会…...

4.3MISC流量分析练习-wireshark-https

流量分析题目的例题 1.了解wireshark的过滤方式 2.了解tls跟ssl协议基本还原 3.了解xor基本变换方式&#xff0c;获取flag 附件是一个流量包&#xff0c;打开之后有各种流量&#xff0c;但是分析无果&#xff0c;然后丢到kali中使用binwalk进行分析&#xff0c;发现有一个r…...

【AGI】DeepSeek开源周:The whale is making waves!

DeepSeek开源周&#xff1a;The whale is making waves&#xff01; 思维火花引言一、DeepSeek模型体系的技术演进1. 通用语言模型&#xff1a;DeepSeek-V3系列2. 推理优化模型&#xff1a;DeepSeek-R1系列3. 多模态模型&#xff1a;Janus系列 二、开源周三大工具库的技术解析1…...

CSS Selectors

当然&#xff0c;理解纯CSS选择器&#xff08;CSS Selectors&#xff09;对于进行UI自动化测试非常重要。CSS选择器允许您通过元素的属性、层级关系、类名、ID等来精准定位页面上的元素。下面我将详细讲解CSS选择器的常见用法&#xff0c;并结合您的需求提供具体的示例。 1. 基…...

Java Junit框架

JUnit 是一个广泛使用的 Java 单元测试框架&#xff0c;用于编写和运行可重复的测试。它是 xUnit 家族的一部分&#xff0c;专门为 Java 语言设计。JUnit 的主要目标是帮助开发者编写可维护的测试代码&#xff0c;确保代码的正确性和稳定性。 JUnit 的主要特点 注解驱动&…...

3-3 WPS JS宏 遍历文件名获取函数(遍历指定文件夹下的所有工作)学习笔记

************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...

STM32CubeMx DRV8833驱动

一、DRV8833驱动原理 ​ STBY口接单片机的IO口&#xff0c;STBY置0电机全部停止&#xff0c;置1才能工作。STBY置1后通过AIN1、AIN2、BIN1、BIN2 来控制正反转。 AIN1AIN2电机状态00停止1speed反转speed1正转11停止 其中A端&#xff08;AIN1与AIN2&#xff09;只能控制AO1与…...