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

【数据结构】AVL树(C++实现)

文章目录

  • 前言
  • AVL树节点的定义
  • AVL树的插入
  • AVL树的旋转
  • AVL树的验证
  • AVL树的删除
  • AVL树的性能与源码




前言


二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson - Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。

一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:

  • 它的左右子树都是AVL树
  • 左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)

在这里插入图片描述
如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在 O ( l o g 2 n ) O(log_2 n) O(log2n),搜索时间复杂度O( l o g 2 n log_2 n log2n)。


AVL树节点的定义


	template<class T>struct TreeNode{public:TreeNode(T data):_data(data), _bf(0), _parent(nullptr), _left(nullptr), _right(nullptr){}public:T _data;// Defining balance factorint _bf;  // 该节点的平衡因子// 定义成一个三叉链结构,方便后续操作TreeNode* _parent;  // 该节点的双亲TreeNode* _left;  // 该节点的左孩子TreeNode* _right;  // 该节点的右孩子};


AVL树的插入


因为插入逻辑比较复杂,我在这里就写一个大致思路,具体代码我上传到了git上。

AVL树就是在二叉搜索树的基础上引入了平衡因子,因此AVL树也可以看成是二叉搜索树。那么AVL树的插入过程可以分为两步:

  1. 按照二叉搜索树的方式插入新节点
  2. 调整节点的平衡因子

此处我写一个大致的代码逻辑,并结合图片给大家看一下:

bool Insert(const T& data)
{// 1. 先按照二叉搜索树的规则将节点插入到AVL树中// ...// 2. 新节点插入后,AVL树的平衡性可能会遭到破坏,此时就需要更新平衡因子,// 并检测是否破坏了AVL树的平衡性/*cur插入后,parent的平衡因子一定需要调整,在插入之前,parent的平衡因子分为三种情况:-1,0, 1, 插入时出现以下两种情况:1. 如果cur插入到parent的左侧,只需给parent的平衡因子-1即可2. 如果cur插入到pParent的右侧,只需给parent的平衡因子+1即可此时:parent的平衡因子可能有三种情况:0,正负1, 正负21. 如果parent的平衡因子为0,说明插入之前pParent的平衡因子为正负1,插入后被调整成0,此时满足AVL树的性质,插入成功2. 如果parent的平衡因子为正负1,说明插入前parent的平衡因子一定为0,插入后被更新成正负1,此时以pParent为根的树的高度增加,需要继续向上更新3. 如果parent的平衡因子为正负2,则parent的平衡因子违反平衡树的性质,需要对其进行旋转处理*/while (parent){// 更新双亲的平衡因子if (cur == parent->_pLeft)parent->_bf--;elseparent->_bf++;// 更新后检测双亲的平衡因子if (0 == parent->_bf){break;}else if (1 == pParent->_bf || -1 == pParent->_bf){// 插入前双亲的平衡因子是0,插入后双亲的平衡因为为1 或者 -1 ,说明以双亲为根的二叉树// 的高度增加了一层,因此需要继续向上调整cur = pParent;pParent = pCur->_pParent;}else{// 双亲的平衡因子为正负2,违反了AVL树的平衡性,需要对以parent// 为根的树进行旋转处理if (2 == pParent->_bf){// ...}else{// ...}}}return true;
}

在这里插入图片描述

插入节点会影响新增节点的部分祖先,
更新规则:

  • c是p的左边,p->_bf--
  • c是p的右边,p->_bf++

是否要继续更新取决于p的高度是否变化,是否会影响爷爷节点。

在上面这张图的基础上,插入11:
请添加图片描述
我们可以看到:

  • 更新后,p->_bf == 0,p所在的高度不会改变,不会影响爷爷节点。说明更新前,p->_bf是1或者-1,p的矮的那一边插入了新节点,左右高度均衡了,p的高度不变,不会影响爷爷,更新结束。
  • 更新后,p->_bf == 1 / -1,p所在的子树高度变了,会影响爷爷。说明更新前,p->_bf是0,p的有一边插入,p变得不均衡,但不违反规则,p的高度变了,会影响爷爷,继续往上更新

在上面这张图的基础上,再插入1:
在这里插入图片描述

  • 更新后,p->_bf == 2 / -2,说明p所在的子树违反了平衡规则,需要进行旋转处理。


AVL树的旋转


如果在一棵原本是平衡的AVL树中插入一个新节点,可能造成不平衡,此时必须调整树的结构,使之平衡化。根据节点插入位置的不同,AVL树的旋转分为四种:

1. 新节点插入较高左子树的左侧—左左:右单旋
在这里插入图片描述

/*上图在插入前,AVL树是平衡的,新节点插入到30的左子树(注意:此处不是左孩子)中,30左子树增加了一层,导致以60为根的二叉树不平衡,要让60平衡,只能将60左子树的高度减少一层,右子树增加一层,即将左子树往上提,这样60转下来,因为60比30大,只能将其放在30的右子树,而如果30有右子树,右子树根的值一定大于30,小于60,只能将其放在60的左子树,旋转完成后,更新节点的平衡因子即可。在旋转过程中,有以下几种情况需要考虑:1. 30节点的右孩子可能存在,也可能不存在2. 60可能是根节点,也可能是子树如果是根节点,旋转完成后,要更新根节点如果是子树,可能是某个节点的左子树,也可能是右子树大家在此处可举一些详细的例子进行画图,考虑各种情况,加深旋转的理解
*/
void RotateR(Node* parents)
{// SubL: parents的左孩子// SubLR: parents左孩子的右孩子,注意:该节点可能为空Node* SubL = parents->_left;Node* SubLR = SubL->_right;// 旋转完成之后,30的右孩子作为双亲的左孩子parents->_left = SubLR;// 如果30的左孩子的右孩子存在,更新该节点的双亲if (SubLR != nullptr)SubLR->_parent = parents;// 60 作为 30的右孩子SubL->_right = parents;// 因为60可能是棵子树,因此在更新其双亲前必须先保存60的双亲Node* ppnode = parents->_parent;// 更新60的双亲	parents->_parent = SubL;// 更新30的双亲SubL->_parent = ppnode;// 如果60是根节点,更新指向根节点的指针if (_root == parents){_root = SubL;SubL->_parent = nullptr;}else{ // 如果60是子树,可能是其双亲的左子树,也可能是右子树if (parents == ppnode->_left)ppnode->_left = SubL;elseppnode->_right = SubL;}// Renewal balance factorparents->_bf = 0;SubL->_bf = 0;
}

2. 新节点插入较高右子树的右侧—右右:左单旋

在这里插入图片描述
实现及情况考虑可参考右单旋:

void RotateL(Node* parents)
{Node* SubR = parents->_right;Node* SubRL = SubR->_left;parents->_right = SubRL;if (SubRL != nullptr)SubRL->_parent = parents;SubR->_left = parents;Node* ppnode = parents->_parent;parents->_parent = SubR;SubR->_parent = ppnode;if (_root == parents){_root = SubR;SubR->_parent = nullptr;}else{if (parents == ppnode->_left)ppnode->_left = SubR;elseppnode->_right = SubR;}// Renewal balance factorparents->_bf = 0;SubR->_bf = 0;
}

3. 新节点插入较高左子树的右侧—左右:先左单选再右单旋
在这里插入图片描述
将双旋变成单旋后再旋转,即:先对30进行左单旋,然后再对90进行右单旋,旋转完成后再考虑平衡因子的更新。
旋转之前先看60的平衡因子是多少,旋转结束以后,根据60的平衡因子更新结果。
这里平衡因子的更新有三种情况:

  1. 旋转之前,60的平衡因子为-1
    在这里插入图片描述

  2. 旋转之前,60的平衡因子为1
    在这里插入图片描述

  3. 旋转之前,60的平衡因子为0
    在这里插入图片描述

从这三张图中,可以发现,不管旋转之前60的平衡因子是多少,最后都会变成0(在单旋中,已经将它置0),所以我们只用观察30,90 的平衡因子。而不管这棵树怎么变,它必定会遵守搜索二叉树的规则,所以在这里我只是用了一个示例向大家展示这三种情况。不管这棵树的形状是什么样的,只要它满足搜索二叉树的规则,那么左右双旋只会有这几种情况。

// 旋转之前,60的平衡因子可能是-1/0/1,旋转完成之后,根据情况对其他节点的平衡因子进行调整
void RotateLR(Node* parents)
{Node* SubL = parents->_left;Node* SubLR = SubL->_right;// 旋转之前,保存pSubLR的平衡因子,旋转完成之后,需要根据该平衡因子来调整其他节点的平衡因子int bf = SubLR->_bf;// 先对30进行左单旋RotateL(SubL);// 再对90进行右单旋RotateR(parents);// Renewal balance factorif (bf == 0){parents->_bf = 0;SubL->_bf = 0;}else if (bf == 1){parents->_bf = 0;SubL->_bf = -1;}else if (bf == -1){parents->_bf = 1;SubL->_bf = 0;}
}

4. 新节点插入较高右子树的左侧—右左:先右单旋再左单旋

在这里插入图片描述

这里与左右双旋相似,将双旋变成单旋后再旋转,即:先对90进行右单旋,然后再对30进行左单旋,旋转完成后再考虑平衡因子的更新。
旋转之前先看60的平衡因子是多少,旋转结束以后,根据60的平衡因子更新结果。
这里平衡因子的更新有三种情况:

  1. 旋转之前,60的平衡因子为1
    在这里插入图片描述

  2. 旋转之前,60的平衡因子为-1
    在这里插入图片描述

  3. 旋转之前,60的平衡因子为0
    在这里插入图片描述

void RotateRL(Node* parents)
{Node* SubR = parents->_right;Node* SubRL = SubR->_left;int bf = SubRL->_bf;RotateR(SubR);RotateL(parents);// Renewal balance factorif (bf == 0){parents->_bf = 0;SubR->_bf = 0;}else if (bf == 1){parents->_bf = -1;SubR->_bf = 0;}else if (bf == -1){parents->_bf = 0;SubR->_bf = 1;}
}

总结
假如以parent为根的子树不平衡,即parent的平衡因子为2或者-2,分以下情况考虑

  1. parent的平衡因子为2,说明parent的右子树高,设parent的右子树的根为SubR
    当SubR的平衡因子为1时,执行左单旋
    当SubR的平衡因子为-1时,执行右左双旋
  2. parent的平衡因子为-2,说明parent的左子树高,设parent的左子树的根为SubL
    当SubL的平衡因子为-1时,执行右单旋
    当SubL的平衡因子为1时,执行左右双旋
    旋转完成后,原parent为根的子树个高度降低,已经平衡,不需要再向上更新。

AVL树的旋转只有以上情况,不可能会出现其他情况了。


AVL树的验证


AVL树是在二叉搜索树的基础上加入了平衡性的限制,因此要验证AVL树,可以分两步:

  1. 验证其为二叉搜索树
    如果中序遍历可得到一个有序的序列,就说明为二叉搜索树
  2. 验证其为平衡树
    • 每个节点子树高度差的绝对值不超过1(注意节点中如果没有平衡因子)
    • 节点的平衡因子是否计算正确
bool Isbalance()
{int Hight = 0;return _Isbalance(_root, Hight);
}
// 为了提高效率,可以走后序来计算每个节点的左子树和右子树的高度差为多少
// 通过Hight来保存每个节点的最高的子树的高度为多少
bool _Isbalance(Node* root, int& Hight)
{if (root == nullptr)return true;int leftHight = 0;int rightHight = 0;if (!_Isbalance(root->_left, leftHight) || !_Isbalance(root->_right, rightHight)){// 如果root的左子树或者右子树不平衡,就直接返回falsereturn false;}// 判断每个节点的左右子树高度差的绝对值不超过1if (abs(rightHight - leftHight) >= 2){std::cout << "balance factor error, the tree is unbalanced\n";return false;}// 判断每个节点的右子树的最大高度与左子树的最大高度的差值是否等于该节点的平衡因子else if (rightHight - leftHight != root->_bf){std::cout << root->_data << " the balance factor is wrong\n";return false;}// 保存左子树和右子树较高的高度Hight = leftHight > rightHight ? leftHight + 1 : rightHight + 1;return true;
}

在这里插入图片描述
这段代码是随机生成10000个数,插入到我自己写的一棵AVL树中,插完这10000个树以后,我对这棵树进行了一下判断是否平衡,结果是平衡的,证明我的插入逻辑是没有问题的(我测试了不止这一组数据)。


AVL树的删除


因为插入删除比较复杂,我在这里就写一个大致思路,具体代码我上传到了git上。

因为AVL树也是二叉搜索树,可按照二叉搜索树的方式将节点删除,然后再更新平衡因子,只不
过与插入不同的是,删除节点后的平衡因子更新,最差情况下一直要调整到根节点的位置。

这里更新平衡因子的逻辑与插入更新平衡因子的逻辑恰恰是相反的。

在这里插入图片描述

删除节点会影响删除节点的部分祖先(如果是删除根节点,也会找一个可以替代的节点交换值再删除,具体可以参考搜索二叉树的删除部分)。
更新原则:

  • c是p的左边,p->_bf++
  • c是p的右边,p->_bf--

是否要继续更新取决于p的高度是否变化,是否会影响爷爷节点。

在上面这张图的基础上,删除7:
在这里插入图片描述
在上面这张图的基础上,再删除3:
在这里插入图片描述
在上面这张图的基础上,再删除14:
在这里插入图片描述

从上面三个动图可以分析出:

  • 更新后p->_bf == 1 / -1,p所在的子树高度不变,不会影响爷爷。说明更新前,p->_bf是0,p的两边是均衡的,p的有一边删除了,p变得不均衡,但不违反规则,p的高度不变,不会影响爷爷,更新结束。
  • 更新后,p->_bf == 0,p所在的子树的高度变了,会影响爷爷。说明更新前,p->_bf == 1 / -1,p的有一边删除了,p的左右变得均衡,p的高度变了,会影响爷爷,继续往上更新。
  • 更新后,p->_bf == 2 / -2,说明p所在的子树违反了平衡规则,需要进行旋转处理。


AVL树的性能与源码


AVL树是一棵绝对平衡的二叉搜索树,其要求每个节点的左右子树高度差的绝对值都不超过1,这样可以保证查询时高效的时间复杂度,即 l o g 2 ( N ) log_2(N) log2(N)。但是如果要对AVL树做一些结构修改的操作,性能非常低下,比如:插入时要维护其绝对平衡,旋转的次数比较多,更差的是在删除时,有可能一直要让旋转持续到根的位置。因此:如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(即不会改变),可以考虑AVL树,但一个结构经常修改,就不太适合。

源码地址:https://gitee.com/ASL498/data-structure/tree/master/AVLTree

相关文章:

【数据结构】AVL树(C++实现)

文章目录 前言AVL树节点的定义AVL树的插入AVL树的旋转AVL树的验证AVL树的删除AVL树的性能与源码 前言 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&…...

AMD新推EPYC与MI325X,挑战英伟达AI市场地位

在人工智能&#xff08;AI&#xff09;加速器领域&#xff0c;AMD近日于美国旧金山举办的“推进人工智能”&#xff08;Advancing AI Event&#xff09;活动中&#xff0c;宣布了一系列新产品的发布&#xff0c;直接对标英伟达&#xff0c;意图在AI芯片市场占据更大份额。 AMD新…...

电脑桌面文件不见了怎么恢复?8个方法帮你解决问题

电脑桌面文件突然不见了凭空消失了怎么恢复&#xff1f;电脑桌面文件日常使用电脑时&#xff0c;很多用户喜欢将重要文件、快捷方式存放在桌面上&#xff0c;以方便快速访问。然而&#xff0c;有时我们会突然发现桌面上的文件不见了。桌面文件消失可能有多种原因&#xff0c;例…...

如果想转行AI领域却不知如何开始?可以试试这五步,超详细_ai行业怎么入行

我看了计算机科学家大卫格维茨写的一篇博客&#xff0c;里面介绍了如果想从事AI行业&#xff0c;却不知道如何开始的话&#xff0c;可以走下面五步&#xff0c;从而达到转行的目的。因为这是个国外作家写的&#xff0c;跟我们国内的情况有一些出入&#xff0c;但是大思路是没有…...

个人博客搭建 | Hexo框架

文章目录 1.Hexo安装2.创建博客3.将博客通过GitHub来部署4.更换主题 1.Hexo安装 Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown&#xff08;或其他标记语言&#xff09;解析文章&#xff0c;在几秒内&#xff0c;即可利用靓丽的主题生成静态网页。搭建Hexo首先要…...

[Gtk] layout.ui

播放器layout&#xff1a; # <?xml version"1.0" encoding"UTF-8"?> <!-- Generated with glade 3.38.2 --> <interface> <requires lib"gtk" version"3.20"/> <object class"GtkWindow"…...

Spring MVC:精通JSON数据返回的几种高效方式

前言 在实际开发中&#xff0c;我们在前后端传送数据通常使用Json格式&#xff0c;而在Spring MVC中返回Json格式的方式有多种&#xff0c;接下来我将介绍其中一些。 准备工作 为了演示Json格式的数据&#xff0c;我们准备一个实体类&#xff0c;例如User&#xff0c;这些可以测…...

[LeetCode 题3] 没有重复字符的最长的子字符串

问题描述 输入&#xff1a;一个字符串 s。输出&#xff1a;最长的无重复字符的子串的长度。 示例 输入: s "abcabcbb" 输出: 3 解释: 最长的无重复字符的子串是 "abc"&#xff0c;长度为 3。 输入: s "bbbbb" 输出: 1 解释: 最长的无重复字…...

YoloDotNet 在工业检测中的应用详解

文章目录 一、数据收集与标注二、模型选择与训练三、检测流程设计四、结果评估与优化五、与工业生产线集成一、数据收集与标注 在工业检测中,首先需要收集大量的相关工业产品图像数据。这些数据应涵盖不同的产品类型、缺陷种类以及各种可能的生产状态。例如,对于电子产品的检…...

DataFrame增删改数据

目录 准备数据 DataFrame添加列 直接添加列数据 使用insert添加列数据 DataFrame删除行列 准备数据 删除行 删除列 DataFrame数据去重 准备数据 import pandas as pd df pd.read_csv("../data/b_LJdata.csv") df DataFrame添加列 直接添加列数据 1&…...

一站式解决App下载量统计,Xinstall引领新潮流

在移动应用市场中&#xff0c;App下载量是衡量应用受欢迎程度和市场表现的重要指标。然而&#xff0c;对于许多开发者而言&#xff0c;如何精准统计App下载量却是一个不小的挑战。幸运的是&#xff0c;如今有了一款专业的App全渠道统计服务商——Xinstall&#xff0c;它能够帮助…...

ijkMediaPlayer+ TextureView 等比全屏播放视频(避免拉伸)

TextureView默认以fitxy的方式加载surface数据&#xff0c;如果需要等比全屏播放视频&#xff0c;避免拉伸&#xff0c;可以采用Matrix对TextureView进行变换 废话不多说&#xff0c;直接上代码 public class BaseIjkPlayer implements TextureView.SurfaceTextureListener{/…...

【RS】GEE(Python):数据处理

在前面的章节中&#xff0c;我们已经学习了如何加载影像数据。现在&#xff0c;让我们进一步探讨如何在 Google Earth Engine (GEE) 中进行数据处理。数据处理通常包括图像预处理、裁剪、过滤、重采样等操作。 栅格影像的处理 栅格影像处理包括了裁剪、波段选择、重采样、合成…...

非线性磁链观测器推导

<div id"content_views" class"htmledit_views"><p id"main-toc"><strong>目录</strong></p> 电机方程 电压方程 磁链方程 定义状态变量和输出变量 非线性观测器方程 电角度的计算--锁相环 锁相环调参 电机…...

什么时机用mysql,什么时机用redis,什么时机用本地内存

mysql 的 buffer pool 也是存在内存中&#xff0c;redis 的数据也是存在内存中&#xff0c;为什么不直接存在 mysql 里&#xff1f; 1、数据结构和访问方式 Redis 是一个内存数据库&#xff0c;专门为高效的读写性能而设计。它支持多种数据结构&#xff08;如字符串、列表、哈…...

Redis八股

缓存 缓存穿透 当查询一个不存在的数据&#xff0c;mysql查询不到数据&#xff0c;无法写入缓存&#xff0c;导致每次都请求数据库 解决方法 缓存空数据&#xff0c;当查询结果未空&#xff0c;将结果进行缓存。 简单但是会消耗内存&#xff0c;而且会出现不一致情况。布隆…...

vue3--通用 popover 气泡卡片组件实现

背景 在日常开发中,我们一般都是利用一些诸如:element-ui、element-plus、ant-design等组件库去做我们的页面或者系统 这些对于一些后台管理系统来说是最好的选择,因为后台管理系统其实都是大同小异的,包括功能、布局结构等 但是对于前台项目,比如官网、门户网站这些 …...

Bluetooth Channel Sounding中关于CS Step及Phase Based Ranging相应Mode介绍

目录 BLE CS中Step定义 BLE CS中交互的数据包/波形格式 BLE CS中Step的不同Mode BLE CS中Step的执行过程 Mode0介绍 Mode0 步骤的作用 Mode0步骤的执行过程 Mode0步骤的执行时间 Mode0步骤的时间精度要求 Mode2介绍 Mode2步骤的作用和执行过程 Mode2步骤的执行时间 B…...

简易STL实现 | Queue 的实现

封装&#xff1a; std::queue 在底层容器的基础上 提供了封装。默认情况下&#xff0c;std::queue 使用 std::deque 作为其底层容器&#xff0c;但也可以配置为使用 std::list 或 其他符合要求的容器 时间复杂度&#xff1a; 入队和出队操作 通常是 常数时间复杂度&#xff08…...

【hot100-java】LRU 缓存

链表篇 灵神题解 class LRUCache {private static class Node{int key,value;Node prev,next;Node (int k,int v){keyk;valuev;}}private final int capacity;//哨兵节点private final Node dummynew Node(0,0);private final Map<Integer,Node> keyToNode new HashMap&l…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...