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

数据结构--树二叉树顺序结构存储的二叉树(堆)

前言

前面我们学习了顺序表、链表、栈和队列,这些都是线性的数据结构。今天我们要来学习一种非线性的数据结构——树。

11c6b0b6e2654f0abe03cb8ed3e57cb8.png

树的概念及结构

树的概念

树是一种非线性的数据结构,是由n(n≥0)个有效结点组成的一个具有层次关系的集合。

  • 树有一个特殊的结点——根结点 根结点没有前驱结点。
  • 除根结点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1≤i≤m)又是一颗结构与树类似的子树。每棵子树的根结点有且只有一个前驱,但可以有0个或多个后继。
  • 因此,树是递归定义的。

6489b5ac43024e5d8bfc40e946b09da5.jpg

 注意:树形结构中,子树之间不能有交集,否则就不是树形结构。

af87886766754ce49997ec1dee7023ed.png

与树相关的概念

a45cba2adf384d05a58a0aa4bd39d58d.png

 

节点的度:一个节点含有的子树的个数称为该节点的度。(如上图中节点A的度为6)

树的度:一棵树中,最大的节点的度称为树的度。(如上图中树的度为6)

叶子节点或终端节点:度为0的节点为叶子节点。(如上图中B、C、H、I、P、Q、K、L、M、N都为叶子节点)

非终端节点或分支节点:度不为0的结点。(如上图中D、E、J、F、G节点为分支节点)

双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点。(例如,A是B的父节点)

孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点。(例如,B是A的孩子节点)

兄弟节点:具有相同父节点的节点互称为兄弟节点。(例如,B和C互为兄弟节点)

堂兄弟节点:双亲在同一层的节点互为堂兄弟。(例如,H和I互为堂兄弟节点)

节点的祖先:从根节点到该节点所经过分支上的所有节点。(上图中A是所有节点的祖先)

子孙:以某节点为根的子树中任意一个节点都称为该节点的子孙。(如上图中,所有节点都是A的子孙)

树的高度或深度:树中节点的最大层次。(上图中,树的高度为4)

森林:由m(m>0)棵互不相交的树的集合称为森林。
 

树的表示

树的结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了。既要保存值域,又要保存结点和结点之间的关系,实际中树有很多种表示方式,如:双亲表示法、孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。在这里,我们简单了解比较常用的孩子兄弟表示法

左孩子右兄弟

c483f4db00514fe7bc185e499efd47d1.png

树在实际中的运用

树在实际中的运用:表示文件系统的目录结构。

我们一起来看一下树在Linux树状目录结构和Windows文件系统层次结构中的应用。

  • Linux树状目录结构

ecf1ce6971284bc683e6d19fdfbee060.jpg

  •    Windows文件系统层次结构

bfbb45eeaeed4a92b995208ad08dd582.png

这里的C盘、E盘和D盘就是根,每个根下面可以有多个文件或者目录,空目录的话就是当前结构中的叶子节点(不考虑未来可能添加内容的情况下)。

二叉树的概念及结构

概念

二叉树是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树形结构。每个节点最多只能有两棵子树,且有左右之分。

28c4b30e879c4f07b0a2154dd3194a81.png

特殊的二叉树

满二叉树

如果一个二叉树的每一层的结点树都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为k,且结点总数是2ᵏ-1,那它就是满二叉树。

完全二叉树

完全二叉树是效率很高的数据结构,它是由满二叉树引来的。对于深度为k的且有n个结点的二叉树,当且仅当它每一个结点都与深度为k的满二叉树中的编号从1到n的结点一一对应时,则称之为完全二叉树。满二叉树是一种特殊的完全二叉树。(如一个完全二叉树有h层,那它前h-1层是满二叉树,最后一层要求从左到右都是连续的。

我们通过一张图片能更好地理解满二叉树和完全二叉树的结构:

c09f5c3dec1d4b44bf7583cb852a7a54.jpeg

二叉树的性质

我们令一棵二叉树里叶子结点的数量为n0,度为2的分支结点的数量为n2,高度为h,一共有n个结点。

  1. n0=n2+1
  2. 如果该二叉树为满二叉树,那么它一共有2ʰ-1个结点227a98b7ba904060a60c84350e59b428.png
  3. 如果该二叉树为完全二叉树,那么它的节点数量的范围为[2ʰ⁻¹,2ʰ-1]
  4. 非空二叉树的第i层最多有2ⁱ⁻¹个节点
  5. 如果该二叉树为满二叉树,那么它的深度h=log₂(n+1)
  6. 父节点与孩子结点在数组中的下标关系(具体见二叉树的顺序结构部分的讲解)。

二叉树的存储结构

在讲二叉树的存储结构之前,我们要先弄懂逻辑结构和物理结构的概念。

逻辑结构描述了数据元素之间的逻辑关系,而物理结构则描述了数据元素在计算机中的存储方式。

我们以链表为例进行讲解,帮助我们更好地理解这两个概念:

f8541eb5deaf4b21b8875b0629a668e3.jpg二叉树一般可以使用两种存储结构:顺序结构和链式结构。

二叉树的顺序结构

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储。

(ps:需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。)

父节点与孩子结点在数组中的下标关系

如果该二叉树为完全二叉树,按照从上到下、从左到右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

  1. i>0时,i位置节点的双亲序号为(i-1)/2;i=0时,i为根节点编号,无双亲节点。
  2. 2i+1<n时,左孩子序号为2i+1(2i+1≥n,否则无左孩子)。
  3. 2i+1<n时,右孩子序号为2i+2(2i+2≥n,否则无右孩子)。

e39ce3fe6fda4e2ba775d7369dfb074f.jpg

这种存储方式更适合存储满完全二叉树;如果存储其他二叉树,由于结构的特点会出现浪费空间的情况。我们通过一张非完全二叉树的顺序存储图片来理解为什么会出现浪费的情况:

b3e83438cb9843a4bb8eebcdb172f9af.jpg

什么是堆?

堆是一种特殊的完全二叉树,通常分为最大堆(大根堆)和最小堆(小根堆):

  1. 最大堆:每个节点的值都大于或等于其子节点的值。这意味着根节点的值是整棵树中的最大值。
  2. 最小堆:每个节点的值都小于或等于其子节点的值。这意味着根节点的值是整棵树中的最小值。

f42e290f67094ff1a00041a33400ec79.png

后续二叉树顺序结构的实现我们主要来实现堆。

二叉树的实现(堆的实现)

堆的数据结构

#define INIT_CAPACITY 4 //初始化堆可容纳的数据个数typedef int dataType;
typedef struct Heap
{dataType* a;//指向堆中实际存储数据的数组int size;//堆中当前存储的元素个数int capacity;//堆的容量,即堆最多可以存储多少个元素
}heap;

初始化堆

void initHeap(heap* pheap)
{assert(pheap);pheap->a = (dataType*)malloc(sizeof(dataType) * INIT_CAPACITY);if (pheap->a == NULL) {perror("malloc fail");return;}pheap->capacity = INIT_CAPACITY;pheap->size = 0;printf("The heap has been initialized.\n");
}

因为这里的堆是基于数组来实现的,所以它的初始化初始化跟前面顺序表的初始化很相似。

堆的插入

向上调整法

堆的插入需要用到向上调整法,以大顶堆为例,现在我们有一个数组模拟出来的大顶堆:

19ef638cd29f41f6b7f0af2fb53ca80e.png

接下来我们要往堆中插入数据80:

1b4cec447bd24ee7ab003f11ee94e12c.png

         ①                    ②                ③                 ④

我们先看图①,在这个大顶堆中,新插入的80比当前堆顶元素数据70大,所以要让80成为这个大顶堆的堆顶元素。从前面我们知道,通过父子结点之间的下标关系,我们很容易调整父子结点之间的位置。所以我们让80(下标为7)作为孩子节点,让它与它的父节点10(下标为3)比较大小,发现孩子节点比父节点大,所以我们交换两个节点的位置就达到了图②的效果。

图②中的80与10交换位置后,新插入节点的下标得到了更新:80节点的下标变为3,10节点的下标变为7,所以父子的关系也会改变。此时80节点的成为了10节点的父节点,80节点的父节点是下标为1的60节点。准备继续比较新插入节点与它更新下标后父节点的大小:由于80与它的父节点里的数据60比较后还是80大,所以还要进行调整,60节点与80节点交换位置,就达到了图③的效果。

以此类推,80与70交换位置,最终80成了堆顶元素。

向上调整法的时间复杂度是多少呢?我们预估最坏的情况,就是新插入的元素比当前堆中所有元素的数据都大,那他就要调整的次数就是h-1次(难以理解就配合上面例子中的图片去理解)h-1=log₂(n+1),所以它的时间复杂度就是log₂n。

代码

void swap(dataType* x, dataType* y)
{dataType tmp = *x;*x = *y;*y = tmp;
}
void adjustUp(dataType* a, int child)
{assert(a);int parent = (child - 1) / 2;//求新插入节点的父节点下标while (child > 0) //关于这个退出条件,后面会讲解{if (a[child] > a[parent]) {//新插入的节点数据大于父节点数据的情况:swap(&a[parent], &a[child]);//交换父子结点的位置//更新新插入节点的下标,准备继续比较它与更新下标后父节点的大小child = parent;parent = (child - 1) / 2;}else {//新插入节点的数据小于或等于父节点的数据,符合大顶堆,直接退出循环break;}}
}
void pushHeap(heap* pheap, dataType x)
{assert(pheap);if (pheap->size == pheap->capacity) {//容量满了,要插入数据就得扩容dataType* tmp = (dataType*)realloc(pheap->a,sizeof(dataType) * pheap->capacity * 2);if (tmp == NULL) {perror("realloc fail");return;}pheap->a = tmp;pheap->capacity *= 2;}pheap->a[pheap->size] = x;//插入新数据adjustUp(pheap->a, pheap->size);//向上调整法++pheap->size;
}

为什么在adjustUp里面的循环退出条件是child<=0的时候呢?我们知道这里的while循环和里面的内容的主要作用是确保新插入堆中的元素能够“上浮”(也就是向上调整法)到其正确的位置,从而维护堆的性质。而这里的child就是新插入元素在刚插入的时候和以及不断更新位置后下标的位置。有两种情况:第一种情况,如果堆中有节点,且新插入的元素比堆中的任意一个节点的数据都大,那它的的下标位置在“上浮”过程中会更新到0,也就说明已经到了堆顶位置,不用再“上浮”了;第二种情况,如果堆本来就为空,那么新插入元素的下标就是0,也不需要“上浮”来调整位置。

总结

1.检查并扩容(如需):若堆满,则扩容。
2.末尾插入:将新元素添加到堆数组的末尾。
3.向上调整:
   从新元素开始,与其父节点比较。
   若新元素大,则交换位置,并继续向上比较直至不需交换或到达根节点。
4.更新大小:堆大小加1。

堆的删除

在堆的数据结构中,特别是二叉堆(包括大顶堆和小顶堆),堆顶元素总是具有特定的性质:在大顶堆中,堆顶是最大的元素;在小顶堆中,堆顶是最小的元素。因此,删除堆顶元素是堆操作中的一个核心功能,这一操作在很多堆的应用中都至关重要,所以我们主要讲解堆顶元素的删除。

向下调整法

堆的删除需要用到向下调整法,还是以大顶堆为例:

aa1c2df1d26e48aa9740b8919bb2a49b.png

我们要删除堆顶元素80:

4cf4f7eaf0ee48a8af792e2014cb19f3.png

        ①                 ②                   ③                  ④

我们看图①,我们先把要删除的堆顶元素80和堆中最后一个元素10交换位置,交换位置后,后面再调整过程中我们就不用在管这个末尾元素80了(这个末尾元素也就相当于被删除了)。

交换位置后,原来的大顶堆达到了图②的效果。我们发现此刚刚交换上来的元素10所在的位置不符合大顶堆的性质,元素10小于它的两个孩子节点70和30。我们需要把交换上来的元素10与孩子节点中最大的一个交换位置,而最大的孩子节点的数据是70。

交换位置后,达到了图③的效果。此时元素10的下标位置和原来在堆中对应的父子关系也发生了变化——元素10的孩子节点的数据为56和10。我们还是让元素10与孩子节点中最大的那个进行交换。

最终达到了图④的效果。

我们通过前面对向上调整法的时间复杂度的推断,很容易推断出这里的时间复杂度也是log₂n。

代码

int getMax(dataType* a, int x, int y)
{if (a[x] > a[y]){return x;}else {return y;}
}
void adjustDown(dataType* a, int parent, int size)
{assert(a);while (parent < size)//parent就是原来交换上面的最后一个元素。后续向下调整的过程中,它的下标不能超出当前堆中的最后一个元素的下标{int lChild = 2 * parent + 1, rChild = 2 * parent + 2;//更新parent的孩子节点的下标int swapChild;//用来记录parent最大的孩子节点的下标if (rChild < size) {//如果parent有两个孩子节点,求出最大的孩子节点的下标swapChild = getMax(a, lChild, rChild);}else {//如果此时parent只有一个孩子,那肯定是左孩子,swapChild直接保存左孩子的下标swapChild = lChild;}if (swapChild < size && a[parent] < a[swapChild]) {//如果父节点小于其最大的孩子,则交换它们,并将parent更新为交换后的孩子下标,以便继续向下调整。swap(&a[parent], &a[swapChild]);parent = swapChild;}else {//如果父节点不小于其孩子,或者已经到达堆的底部,则停止调整。break;}}
}
void popHeap(heap* pheap)
{assert(pheap);if (pheap->size == 0) {//堆中无元素,就不能再删除元素了printf("The heap has been already emtied!\n");return;}swap(&pheap->a[0], &pheap->a[pheap->size - 1]);//先把要删除的堆顶元素和堆中最后一个元素交换位置--pheap->size;//交换位置后,删除此时最后一个元素adjustDown(pheap->a, 0, pheap->size);//向下调整法,使得交换位置后的堆符合大顶堆的性质}

总结

1.检查非空:若堆为空,则直接返回。
2.交换并减小:将堆顶与末尾元素交换,然后减小堆大小。
3.向下调整:从新的堆顶开始,与其孩子比较并交换(如需),直至堆性质恢复或到达堆底。

判断堆是否为空

bool isEmpty(heap* pheap)
{assert(pheap);if (pheap->size == 0) {return true;}else {return false;}
}

获取堆顶元素

dataType topHeap(heap* pheap)
{assert(pheap);assert(!isEmpty(pheap));return pheap->a[0];
}

获取堆里的元素个数

int sizeHeap(heap* pheap)
{assert(pheap);return pheap->size;
}

测试案例

void test() {heap hp;initHeap(&hp);pushHeap(&hp, 80);pushHeap(&hp, 10);pushHeap(&hp, 56);pushHeap(&hp, 30);pushHeap(&hp, 60);pushHeap(&hp, 70);pushHeap(&hp, 25);pushHeap(&hp, 15);for (int i = 0; i < sizeHeap(&hp); i++) {printf("%d ", hp.a[i]);}printf("\n");while (!isEmpty(&hp)) {popHeap(&hp);}if (isEmpty(&hp)) {printf("The heap has been emptied!\n");}destroyedHeap(&hp);
}

 

 

相关文章:

数据结构--树二叉树顺序结构存储的二叉树(堆)

前言 前面我们学习了顺序表、链表、栈和队列&#xff0c;这些都是线性的数据结构。今天我们要来学习一种非线性的数据结构——树。 树的概念及结构 树的概念 树是一种非线性的数据结构&#xff0c;是由n&#xff08;n≥0&#xff09;个有效结点组成的一个具有层次关系的集合…...

mongodb shard 分片集群基础概念

目录 一、shard 集群 二、Config Server 1、config.shards 2、config.database 3、config.collection 4、config.chunks 5、config.settings 6、其他 三、shard机制 1、Primary Shard 2、Shard Key 2.1 范围分片 2.2 哈希分片 2.3 Shard Key重定义 2.4 版本约束…...

Streamlit 应用从本地部署到服务器并进行访问

目录 1 部署 Streamlit 应用到服务器2 配置服务器允许远程访问3 使用反向代理4 使用 HTTPS5 总结 1 部署 Streamlit 应用到服务器 1 选择一个服务器平台 首先&#xff0c;你需要选择一个服务器平台来部署你的 Streamlit 应用。常见的选择包括&#xff1a; 云服务器&#xff1a…...

大数据新视界 -- 大数据大厂之 Hive 数据压缩:优化存储与传输的关键(上)(19/ 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

Java开发中对List<Map<String, Object>>集合去重并按大小拆分子列表

Java开发中对List< Map< String, Object > >集合去重并按大小拆分子列表 一、使用场景二、实现步骤三、相关知识四、代码示例 一、使用场景 在处理大量List<Map<String, Object>>集合的数据时&#xff0c;为确保数据的唯一性&#xff0c;需要先根据Ma…...

vue3项目搭建-6-axios 基础配置

axios 基础配置 安装 axios npm install axios 创建 axios 实例&#xff0c;配置基地址&#xff0c;配置拦截器,目录&#xff1a;utils/http.js 基地址&#xff1a;在每次访问时&#xff0c;自动作为相对路径的根 // axios 基础封装 import axios from "axios";…...

git 学习笔记

目录 一、git 前期准备 1、托管平台的账号注册&#xff08;以gitee码云为demo&#xff09; 2、本地个人电脑配置 &#xff08;1&#xff09;配置用户属性 &#xff08;2&#xff09;配置SSH密钥 二、git 工作流程图 三、git 提交命令 &#xff08;1&#xff09;git ini…...

Y20030019 基于java+jsp+mysql的微信小程序校园二手交易平台的设计与实现 源代码 文档

旅游度假区微信小程序 1.摘要2. 系统开发的目的和意义3.系统功能4.界面展示5.源码获取 1.摘要 随着移动互联网的发展&#xff0c;微信小程序已经成为人们生活中不可或缺的一部分。微信小程序的优点在于其快速、轻量、易用&#xff0c;用户无需下载即可使用&#xff0c;节省了用…...

Cookie跨域

跨域&#xff1a;跨域名&#xff08;IP&#xff09; 跨域的目的是共享Cookie。 session操作http协议&#xff0c;每次既要request&#xff0c;也要response&#xff0c;cookie在创建的时候会产生一个字符串然后随着response返回。 全网站的各个页面都会带着登陆的时候的cookie …...

Mybatis:CRUD数据操作之删除一行数据

Mybatis基础环境准备请看&#xff1a;Mybatis基础环境准备 本篇讲解Mybati数据CRUD数据操作之单条删除数据 当用户点击了该按钮&#xff0c;就会将改行数据删除掉。那我们就需要思考&#xff0c;这种删除是根据什么进行删除呢&#xff1f;是通过主键id删除&#xff0c;因为id是…...

【机器学习】CatBoost 模型实践:回归与分类的全流程解析

一. 引言 本篇博客首发于掘金 https://juejin.cn/post/7441027173430018067。 PS&#xff1a;转载自己的文章也算原创吧。 在机器学习领域&#xff0c;CatBoost 是一款强大的梯度提升框架&#xff0c;特别适合处理带有类别特征的数据。本篇博客以脱敏后的保险数据集为例&#x…...

MySQL中如何减少回表

在MySQL中&#xff0c;回表是指在使用非聚集索引进行查询时&#xff0c;如果需要获取的数据不在索引页中&#xff0c;就需要根据索引页中的指针返回到数据表中查找实际数据行的过程。这个过程会增加额外的磁盘I/O操作&#xff0c;降低查询性能&#xff0c;特别是在查询大量数据…...

10. 函数

一、什么是函数 函数也是对象&#xff0c;对象是内存中专门用来存储数据的一块区域。函数可以用来保存一些可执行代码的&#xff0c;并且可以在需要时&#xff0c;对这些语句进行多次调用。 二、创建函数 创建函数也称为定义函数。我们可以使用 def 关键字来定义函数&#xff…...

计算机网络:数据链路层(二)

网课资源&#xff1a; 湖科大教书匠 1、网络适配器和MAC地址 习题1 1 以下哪个地址是广播MAC地址 A. 00-00-00-00-00-00 B. AB-CD-EF-11-22-33 C. FF-FF-FF-FF-FF-FF D. 29-29-29-29-29-29 2 以下哪个地址是多播MAC地址 A. 00-00-00-00-00-00 B. A9-8B-7C-6D-5E-4F C. FF-FF-…...

一万台服务器用saltstack还是ansible?

一万台服务器用saltstack还是ansible? 选择使用 SaltStack 还是 Ansible 来管理一万台服务器&#xff0c;取决于几个关键因素&#xff0c;如性能、扩展性、易用性、配置管理需求和团队的熟悉度。以下是两者的对比分析&#xff0c;帮助你做出决策&#xff1a; SaltStack&…...

设计模式学习之——观察者模式

观察者模式是一种行为型设计模式&#xff0c;它用于在对象之间建立一对多的依赖关系。 一、定义与角色 定义&#xff1a; 观察者模式定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时&#xff0c;会通知所有观察…...

服务器实现ssh证书登录

1.生成公钥和私钥 ssh-keygen -t rsa 提示默认生成位置为/root/.ssh/id_rsa ,直接回车。(也可以自己修改) 提示输入证书的密码&#xff0c;可以留空&#xff0c;建议输入&#xff0c;如果输入了&#xff0c;则需要再次确认&#xff0c;记住这个证书密码&#xff08;证书再加…...

python基础知识精讲

Python基础知识精讲 Python是一种广泛使用的高级编程语言&#xff0c;以其清晰的语法和代码可读性而闻名。它支持多种编程范式&#xff0c;包括面向对象、命令式、函数式和过程式编程。以下是Python基础知识的详细讲解。 1. Python简介 Python由Guido van Rossum创建&#x…...

分页查询日期格式不对

方式一:在属性上加入注解&#xff0c;对日期进行格式化 方式二:在 WebMvcConfiguration 中扩展Spring MVC的消息转换器&#xff0c;统一对日期类型进行格式化处理 /*** 统一转换处理扩展spring mvc* 后端返回前端的进行统一转化处理* param converters*/Overrideprotected voi…...

Windsurf可以上传图片开发UI了

背景 曾经羡慕Cursor的“画图”开发功能&#xff0c;这不Windsurf安排上了。 Upload Images to Cascade Cascade now supports uploading images on premium models Ask Cascade to build or tweak UI from on image upload New keybindings Keybindings to navigate betwe…...

工作坊报名|使用 TEN 与 Azure,探索你的多模态交互新场景

GPT-4o Realtime API 发布&#xff0c;语音 AI 技术正在进入一场新的爆发。语音AI技术的实时语音和视觉互动能力将为我们带来更多全新创意和应用场景。 实时音频交互&#xff1a; 允许应用程序实时接收并响应语音和文本输入。自然语音生成&#xff1a; 减少 AI 技术生成的语音…...

Java 虚拟机:承载 Java 生态的神奇魔盒

在软件开发的世界里&#xff0c;Java 虚拟机&#xff08;JVM&#xff09;就像一位智慧的管家&#xff0c;默默守护着 Java 生态系统的运行。它不仅让 Java 实现了"一次编写&#xff0c;到处运行"的梦想&#xff0c;更是成为了多种编程语言的运行平台。让我们一起走进…...

Linux VLAN 实现原理技术笔记

一、引言 VLAN&#xff08;虚拟局域网&#xff09;在整车网络架构中起着至关重要的作用&#xff0c;它能够在物理网络基础设施上创建逻辑隔离的网络区域&#xff0c;提高车内网络的安全性、灵活性和性能。Linux 内核通过一系列复杂的机制实现了 VLAN 功能&#xff0c;本技术笔记…...

【Git】:分支管理

目录 理解分支 创建分支 切换分支 合并分支 删除分支 合并冲突 分支管理策略 快进合并 正常合并 bug 分支 总结 理解分支 在版本控制系统中&#xff0c;分支是一条独立的开发线路。它允许开发者从一个主要的代码基线&#xff08;例如master分支&#xff09;分离出来…...

Java中的运算符“instanceof“详解

在Java中&#xff0c;instanceof运算符用于检查一个对象是否是某个特定类的实例&#xff0c;或者是否实现了某个特定接口。它返回一个布尔值&#xff08;true或false&#xff09;&#xff0c;用于在运行时进行类型检查。这在处理多态性时尤其有用&#xff0c;可以帮助我们确定对…...

Profinet转Modbus TCP西门子SINAMICS G120变频器与施耐德M580通讯案例

一. 案例背景 在复杂的工业自动化场景中&#xff0c;企业常常会采用不同品牌的设备来构建生产系统。西门子SINAMICS G120变频器以其高性能、高精度的速度和转矩控制功能&#xff0c;在电机驱动领域应用广泛。施耐德M580可编程逻辑控制器则以强大的逻辑控制和数据处理能力著称&a…...

机器学习实战笔记39-43树模型基础

目前最常用的是CART树&#xff1a; 评价标准&#xff1a;每次划分后子节点的纯度&#xff08;即是否标签都为0/1&#xff09;&#xff0c;分为信息熵、基尼系数&#xff08;越小则纯度越高&#xff09;和分类误差 找划分节点的方法&#xff1a;CART树无需区分连续和离散变量&am…...

`uni.setClipboardData` 是 uni-app 提供的一个 API 设置系统剪贴板的内容

uni.setClipboardData是uni-app提供的一个API&#xff0c;用于设置系统剪贴板的内容。 使用说明&#xff1a; 使用此API可以将指定的文本内容复制到系统剪贴板&#xff0c;使用户能够在其他应用或页面中粘贴这些内容。 uni.setClipboardData({data: , // 需要复制的内容 suc…...

Android opengl 绘制矩形,宽高相同,不能显示为正方形,是怎么回事

在Android上使用OpenGL绘制矩形&#xff08;或尝试显示为正方形&#xff09;时&#xff0c;如果结果显示为不是正方形&#xff0c;可能有几个原因。以下是一些常见的因素及解决方法&#xff1a; 视口&#xff08;Viewport&#xff09;设置不当&#xff1a; OpenGL的视口定义了…...

网络安全开源组件

本文只是针对开源项目进行收集&#xff0c;如果后期在工作中碰到其他开源项目将进行更新。欢迎大家在评论区留言&#xff0c;您在工作碰到的开源项目。 祝您工作顺利&#xff0c;鹏程万里&#xff01; 一、FW&#xff08;防火墙&#xff09; 1.1 pfSense pfSense项目是一个免费…...

【C++初阶】第5课—模版初阶

文章目录 1. 函数模版1.1 函数模版格式1.2 函数模版原理1.3 函数模版的实例化1.4 模版参数的匹配原则 2. 类模版 1. 函数模版 在讲函数模版之前先看一个例子 为了实现泛型编程&#xff0c;C提出了函数模版的概念函数模版与类型无关&#xff0c;在使用时被参数化&#xff0c;根据…...

【力扣热题100】[Java版] 刷题笔记-3. 无重复字符的最长子串

题目:3. 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 解题思路 根据题目&#xff0c;只需要返回无重复字符串的最长子串的长度&#xff0c;所以我们不需要知道知道字符串内容是什么&#xff0c;在整个字符串 s 中&…...

无人机数据处理系统:原理与核心系统

一、数据处理系统的运行原理 数据获取&#xff1a;无人机在飞行过程中&#xff0c;通过搭载的传感器&#xff08;如相机、激光雷达等&#xff09;采集到各种类型的数据&#xff0c;例如图像、点云等。这些数据是后续处理和分析的基础。 数据传输&#xff1a;采集到的数据会通…...

Hadoop分布式文件系统(二)

目录 1. 引言1. Hadoop文件操作命令2. 部分常用的Hadoop FS Shell命令2.1 ls列出文件2.2 mkdir创建目录2.3 put上传文件2.4 cat查看文件2.5 get复制文件2.6 rm删除文件 3. Hadoop系统管理命令4. HDFS Java API 示例参考 1. 引言 大多数HDFS Shell命令的行为和对应的Unix Shell命…...

PortSwigger 原型污染

一、什么是原型污染 原型污染是一种 JavaScript 漏洞&#xff0c;它使攻击者能够向全局对象原型添加任意属性&#xff0c;然后这些属性可能被用户定义的对象继承。 二、JavaScript 原型和继承基础 1、原型 JavaScript 中的每个对象都链接到某种类型的另一个对象&#xff0c;称…...

雪花算法详解:分布式系统中高效唯一的ID生成方案

文章目录 原理与结构工作流程优势局限性应对高并发的方法适用场景 雪花算法&#xff08;Snowflake Algorithm&#xff09;是由Twitter开发的一种分布式全局唯一ID生成方案&#xff0c;旨在解决在分布式系统中快速、无冲突地生成唯一标识符的问题。它通过巧妙的设计&#xff0c;…...

[Redis#7] set | 命令 | 集合 | 用户画像 | UV

目录 1. 特点 2. 常用命令 2.1 普通命令 2.2 集合间操作 2.3. 命令小结 3.内部编码 4. 应用场景 1. 构造用户画像 2. 计算用户之间的共同好友 3. 统计 UV 1. 特点 集合类型也是保存多个字符串类型的元素的&#xff0c;和 list 类型不同的是&#xff1a; 无序性&…...

中介者模式 (Mediator Pattern)

文章目录 中介者模式 (Mediator Pattern)原理优点缺点示例代码场景描述1. 定义中介者接口2. 实现具体中介者3. 定义同事类接口4. 实现具体同事类5. 客户端代码输出结果 UML 类图使用场景小结 中介者模式 (Mediator Pattern) 中介者模式是一种 行为型设计模式&#xff0c;用来降…...

PVE 软路由单网口——VLAN 实践

从VLAN交换机出发&#xff0c;到PVE的Linux Bridge 、Linux VLAN&#xff0c;再到iKuai等软路由软件的设置&#xff0c;尽可能的了解VLAN设置细节&#xff0c;避免踩坑。 本文使用的快速切换CIDR的脚本 PVE 调试之“一键设置网络连接的以太网的CIDR“——“.PS1 脚本” 默认…...

搭建一个基于Web的文档管理系统,用于存储、共享和协作编辑文档

搭建一个基于Web的文档管理系统&#xff0c;用于存储、共享和协作编辑文档 本项目采用以下架构&#xff1a; NFS服务器: 负责存储文档资料。Web服务器: 负责提供文档访问和编辑功能。SELinux: 负责权限控制&#xff0c;确保文档安全。Git服务器: 负责存储文档版本历史&#x…...

【QT】控件8

1.QDial 通过调节旋钮位置来控制窗口的不透明度&#xff1a; void Widget::on_dial_valueChanged(int value) {qDebug()<<value;this->setWindowOpacity((double)value/100); }效果演示&#xff1a; 2.Date/Time Edit 计算两个日期的差值 ui界面设计 计算按钮按下…...

asyncio.to_thread 详解及示例代码

asyncio.to_thread 详解及示例代码 1. asyncio.to_thread() 简介函数签名返回值 2. 示例代码示例 1: 执行阻塞的 I/O 操作示例 2: 执行阻塞的 CPU 密集型操作 3. 注意事项4. 总结 在异步编程中&#xff0c;asyncio 是 Python 中用于编写异步代码的标准库。然而&#xff0c;有时…...

MYSQL字段变更

修改字段长度 ALTER TABLE tqt_sp_prod.t_receipt_order_head MODIFY COLUMN CUS_CONTRACT_CD VARCHAR(50) COMMENT 客户合同编号;添加varchar类型字段 AFTER 此处指在loc_cd字段后面 ALTER TABLE m_product ADD COLUMN FIXED_ASSET_NUM VARCHAR(100) DEFAULT NULL COMME…...

【通俗理解】步长和学习率在神经网络中是一回事吗?

【通俗理解】步长和学习率在神经网络中是一回事吗&#xff1f; 【核心结论】 步长&#xff08;Step Size&#xff09;和学习率&#xff08;Learning Rate, LR&#xff09;在神经网络中并不是同一个概念&#xff0c;但它们都关乎模型训练过程中的参数更新。 【通俗解释&#x…...

力扣-位运算-8【算法学习day.48】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…...

C++ 字符串中数字识别

【问题描述】 输入一个字符串&#xff0c;含有数字和非数字字符&#xff0c;如“sumabc234;while(abc700)tab{ass346;bssabc267;}”&#xff0c;将其中连续的数字作为一个整数&#xff0c;依次存放到一个数组nums中。例如&#xff0c;234放在nums[0]&#xff0c;700放在nums[1…...

计算机毕业设计Python+卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

jvm-49-linux 服务器 cpu 使用率升高应该如何排查分析?

拓展阅读 JVM FULL GC 生产问题 I-多线程通用实现 JVM FULL GC 生产问题 II-如何定位内存泄露&#xff1f; 线程通用实现 JVM FULL GC 生产问题 III-多线程执行队列的封装实现&#xff0c;进一步抽象 jvisualvm java 性能分析工具 jvm-44-jvm 内存性能分析工具 Eclipse Me…...

FPGA存在的意义:为什么adc连续采样需要fpga来做,而不会直接用iic来实现

FPGA存在的意义&#xff1a;为什么adc连续采样需要fpga来做&#xff0c;而不会直接用iic来实现 原因ADS111x连续采样实现连续采样功能说明iic读取adc的数据速率 VS adc连续采样的速率adc连续采样的速率iic读取adc的数据速率结论分析 FPGA读取adc数据问题一&#xff1a;读取adc数…...

Web开发基础学习——HTML, CSS, JavaScript 的区别和联系

Web开发基础学习系列文章目录 第一章 基础知识学习之HTML, CSS, JavaScript 的区别和联系 文章目录 Web开发基础学习系列文章目录前言一、定义说白了&#xff0c;就是HTML负责网页的内容&#xff0c;CSS负责网页的格式&#xff0c;JS负责网页的交互。 二、 功能三、联系四、示…...