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

【数据结构】AVL树的实现

文章目录

  • 1. AVL 的概念
  • 2. AVL 树的实现
    • 2.1 AVL 树的结构
    • 2.2 AVL 树的插入
      • 2.2.1 AVL 树插入一个值的大致过程
      • 2.2.2 平衡因子更新
    • 2.3 旋转
      • 2.3.1 旋转的原则
      • 2.3.2 右单旋
      • 2.3.3 左单旋
      • 2.3.4 左右双旋
      • 2.3.5 右左双选
    • 2.4 AVL 树的查找
    • 2.5 AVL 树平衡检测

1. AVL 的概念

  • AVL树是最先发明的自平衡二叉查找树,AVL是一颗空树,或者具备下列性质的二叉搜索树:它的左右子树都是AV树,且左右子树的高度差的绝对值不超过1。AVL树是一颗高度平衡搜索二叉树,通过控制高度差去控制平衡。
  • AVL树得名于它的发明者G.M.Adelson-Velsky和E.M. Landis是两个前苏联的科学家,他们在1962年的论文《An algorithm for the organization of information》中发表了它。
  • AVL树实现这里我们引入一个平衡因子(balancefactor)的概念,每个结点都有一个平衡因子,任何结点的平衡因子等于右子树的高度减去左子树的高度,也就是说任何结点的平衡因子等于0/1/-1,AVL树并不是必须要平衡因子,但是有了平衡因子可以更方便我们去进行观察和控制树是否平衡,就像一个风向标一样。
  • AVL树整体结点数量和分布和完全二叉树类似,高度可以控制在logN,那么增删查改的效率也可以控制在O(logN),相比二叉搜索树有了本质的提升。

在这里插入图片描述
在这里插入图片描述

2. AVL 树的实现

2.1 AVL 树的结构

相比于二叉搜索树,AVL 因为要控制左右子树高度差,所以引入了 平衡因子,而为了更行平衡因子,它又引入了一个 父指针

// 节点结构
template<class K, class V>
struct AVLTreeNode
{// 需要parent指针,后续更新平衡因⼦可以看到pair<K, V> _kv;AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;int _bf; // balance factorAVLTreeNode(const pair<K, V>& kv):_kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0){}
};// AVL树
template<class K, class V>
class AVLTree
{typedef AVLTreeNode<K, V> Node;
public:// ...
private:Node* _root = nullptr;
};

2.2 AVL 树的插入

2.2.1 AVL 树插入一个值的大致过程

  1. 插入一个值按二叉搜索树规则进行插入。
  2. 新增结点以后,只会影响祖先结点的高度,也就是可能会影响部分祖先结点的平衡因子,所以更新从新增结点->根结点路径上的平衡因子,实际中最坏情况下要更新到根,有些情况更新到中间就可以停止了,具体情况我们下面再详细分析。
  3. 更新平衡因子过程中没有出现问题,则插入结束
  4. 更新平衡因子过程中出现不平衡,对不平衡子树旋转,旋转后本质调平衡的同时,本质降低了子树的高度,不会再影响上一层,所以插入结束。

2.2.2 平衡因子更新

更新原则:

  • 平衡因子=右子树高度-左子树高度
  • 只有子树高度变化才会影响当前结点平衡因子。
  • 插入结点,会增加高度,所以新增结点在parent的右子树,parent的平衡因子++,新增结点在parent的左子树,parent平衡因子–
  • parent所在子树的高度是否变化决定了是否会继续往上更新

更新停止条件:

  • 更新后parent的平衡因子等于0,更新中parent的平衡因子变化为-1->0或者1->0,说明更新前parent子树一边高一边低,新增的结点插入在低的那边,插入后parent所在的子树高度不变,不会影响parent的父亲结点的平衡因子,更新结束
  • 更新后parent的平衡因子等于1或-1,更新前更新中parent的平衡因子变化为0->1或者0->-1,说明更新前parent子树两边一样高,新增的插入结点后,parent所在的子树一边高一边低,parent所在的子树符合平衡要求,但是高度增加了1,会影响parent的父亲结点的平衡因子,所以要继续向上更新。
  • 更新后parent的平衡因子等于2或-2,更新前更新中parent的平衡因子变化为1->2或者-1->-2,说明更新前parent子树一边高一边低,新增的插入结点在高的那边,parent所在的子树高的那边更高了,破坏了平衡,parent所在的子树不符合平衡要求,需要旋转处理,旋转的目标有两个:1、把parent子树旋转平衡。2、降低parent子树的高度,恢复到插入结点以前的高度。所以旋转后也不需要继续往上更新,插入结束

更新到10结点,平衡因子为2,10所在的子树已经不平衡,需要旋转处理
在这里插入图片描述
更新到中间结点,3为根的子树高度不变,不会影响上一层,更新结束
在这里插入图片描述
最坏更新到根停止
在这里插入图片描述
插入其实就是在二叉搜索树的插入上增加了更新平衡因子机制,而更新平衡因子时可能需要旋转操作,旋转操作后面在讲。

bool Insert(const pair<K, V>& kv)
{if (_root == nullptr){_root = new Node(kv);return true;}Node* parent = nullptr;Node* cur = _root;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);if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;// 更新平衡因子while (parent){// 更新平衡因子if (cur == parent->_left)parent->_bf--;elseparent->_bf++;if (parent->_bf == 0){// 更新结束break;}else if (parent->_bf == 1 || parent->_bf == -1){// 继续往上更新cur = parent;parent = parent->_parent;}else if (parent->_bf == 2 || parent->_bf == -2){// 不平衡了,旋转处理,旋转部分后文讲if (parent->_bf == -2 && cur->_bf == -1){RotateR(parent);}else if (parent->_bf == 2 && cur->_bf == 1){RotateL(parent);}else if (parent->_bf == -2 && cur->_bf == 1){RotateLR(parent);}else if (parent->_bf == 2 && cur->_bf == -1){RotateRL(parent);}else{assert(false);}break;}else{assert(false);}}return true;
}

2.3 旋转

2.3.1 旋转的原则

  1. 保持搜索树的规则
  2. 让旋转的树从不满足变平衡,其次降低旋转树的高度

旋转总共分为四种,左单旋/右单旋/左右双旋/右左双旋。

2.3.2 右单旋

触发条件

  • 失衡节点A的左子树高度 - 右子树高度 = 2(即平衡因子为-2)。
  • A的左孩子B的平衡因子为-1(即B的左子树更高,形成LL型失衡)。

操作步骤

  1. 提升左孩子B为新的根节点。
  2. 原根节点A成为B的右孩子。
  3. 处理B的右子树:如果B原本有右子树BR,将其作为A的新左子树。
  4. 更新平衡因子:旋转后,A和B的平衡因子均变为0。
失衡结构:A (BF=-2)/B (BF=-1)/C右旋过程:
1. 将B提升为根,A成为B的右孩子:B/ \C   A
2. 原B的右子树(假设为空)无需处理。
最终平衡因子:B(BF=0), A(BF=0)原结构(LL失衡):parent (bf=-2)/subL (bf=-1)/   \X   subLR旋转后:subL (bf=0)/   \X   parent (bf=0)/subLR

代码:

	void RorateR(Node* parent){// 1. 获取左孩子subL及其右子树subLRNode* subL = parent->_left;  // 保存左子树根节点subLNode* subLR = subL->_right;  // 保存subL的右子树// 2. 调整parent和subLR的父子关系parent->_left = subLR;		 // 将subLR挂到parent的左侧if (subLR)					 // 若subKR存在,更新它的父指针subLR->_parent = parent;// 3. 调整subL和parent的父子关系Node* pParent = parent->_parent; // 记录原parent的父节点(可能为空)subL->_right = parent;			 // 将parent作为subL的右孩子parent->_parent = subL;			 // 更新parent的父节点// 4. 将subL连接到原parent的父节点(整棵树的连接)if (parent == root)				 // 若parent是根节点{_root = subL;				 // 更新根节点为subLsubL->_parent = nullptr;	 // 新根节点的父指针置空}else{if (pParent->_left == parent) // 判断原parent是左孩子还是右孩子pParent->_left = subL;    // 将subL挂到原祖父的左elsepParent->_right = subL;   // 将subL挂到原祖父的右subL->_parent = pParent;	  // 更新subL的父指针}// 更新平衡因子subL->_bf = 0;parent->_bf = 0;}

2.3.3 左单旋

触发条件

  • 失衡节点A的平衡因子为+2。
  • A的右孩子B的平衡因子为+1(形成RR型失衡)。

操作步骤

  1. 提升右孩子B为新的根节点。
  2. 原根节点A成为B的左孩子。
  3. 处理B的左子树:如果B原本有左子树BL,将其作为A的新右子树。
  4. 更新平衡因子:A和B的平衡因子均变为0。
失衡结构:A (BF=+2)\B (BF=+1)\C左旋过程:
1. 将B提升为根,A成为B的左孩子:B/ \A   C
最终平衡因子:B(BF=0), A(BF=0)原结构(LL失衡):parent (bf=+2)\subR (bf=+1)/   \subRL   X
旋转后:subR (bf=0)/   \parent    X\subRL

代码就和右单旋刚好相反,不做过多解释:

	void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;Node* pParent = parent->_parent;subR->_left = parent;parent->_parent = subR;if (pParent == nullptr){_root = subR;subR->_parent = nullptr;}else{if (parent == pParent->_left)pParent->_left = subR;elsepParent->_right = subR;subR->_parent = pParent;}parent->_bf = subR->_bf = 0;}

2.3.4 左右双旋

为什么需要双旋转?

  • 单旋转无法解决之字型失衡:例如在LR失衡中,失衡路径是左→右,直接右旋会破坏结构,需先通过左旋将其转化为LL型
  • 平衡因子动态调整:双旋转后需根据中间节点的原始平衡因子重新计算各节点的平衡因子。

先通过单旋调整成上面可以单旋的类型,再通过单旋解决问题。

触发条件

  • 失衡节点A的平衡因子为-2。
  • A的左孩子B的平衡因子为+1(形成LR型失衡,即B的右子树更高)。

操作步骤

  1. 先对B左旋(转化为LL型):
    • 将B的右孩子C提升为A的新左孩子。
    • B成为C的左孩子,C的原左子树成为B的右子树。
  2. 再对A右旋:
    • 将C提升为根,A成为C的右孩子。
  3. 更新平衡因子:
    • 若C原平衡因子为0,则A和B均变为0。
    • 若C原平衡因子为+1,则A(BF=0), B(BF=-1), C(BF=0)。
    • 若C原平衡因子为-1,则A(BF=+1), B(BF=0), C(BF=0)。
初始失衡结构:A (BF=-2)/B (BF=+1)\C (BF=0)步骤1:对B左旋后:A/C/B步骤2:对A右旋后:C/ \B   A
平衡因子:C(BF=0), B(BF=0), A(BF=0)初始结构(LR失衡)parent (bf=-2)/subL (bf=+1)\subLR (bf=-1/0/+1)/   \CL   CR旋转后结构subLR (bf=0)/      \subL       parent/  \       /   \CL   CR_L  CR_R  CR
	void RotateLR(Node* parent){// 1. 获取相关节点Node* subL = parent->_left; // parent的左孩子Node* subLR = subL->_right; // subL的右孩子(subLR,即失衡的中间节点)int bf = subLR->_bf;		// 保存subLR的原始平衡因子// 2. 双旋操作RotateL(parent->_left);		// 先对subL进行左旋(将subLR提升为subL的位置)RotateR(parent);			// 再对parent进行右旋(将subLR提升为根)// 3. 根据subLR的原始平衡因子调整平衡因子if (bf == -1)				// subLR的左子树更高{subLR->_bf = 0;			// 新根subLR平衡因子归零subL->_bf = 0;			// 原左子树subL平衡因子归零parent->_bf = 1;		// 原根parent右子树更高(平衡因子+1)}else if (bf == 1)			// subLR的右子树更高{subLR->_bf = 0;			// 新根subLR平衡因子归零subL->_bf = -1;			// 原左子树subL左子树更高(平衡因子-1)parent->_bf = 0;		// 原根parent平衡因子归零}else if (bf == 0)			// subLR左右子树等高{subLR->_bf = 0;			// 所有相关节点平衡因子归零subL->_bf = 0;parent->_bf = 0;}else{assert(false);}}

2.3.5 右左双选

触发条件

  • 失衡节点A的平衡因子为+2。
  • A的右孩子B的平衡因子为-1(形成RL型失衡,即B的左子树更高)。

操作步骤

  1. 先对B右旋(转化为RR型):
    • 将B的左孩子C提升为A的新右孩子。
    • B成为C的右孩子,C的原右子树成为B的左子树。
  2. 再对A左旋:
    • 将C提升为根,A成为C的左孩子。
  3. 更新平衡因子:
    • 若C原平衡因子为0,则A和B均变为0。
    • 若C原平衡因子为+1,则A(BF=-1), B(BF=0), C(BF=0)。
    • 若C原平衡因子为-1,则A(BF=0), B(BF=+1), C(BF=0)。
初始失衡结构:A (BF=+2)\B (BF=-1)/C (BF=0)步骤1:对B右旋后:A\C\B步骤2:对A左旋后:C/ \A   B
平衡因子:C(BF=0), A(BF=0), B(BF=0)初始结构(RL失衡)parent (bf=+2)\subR (bf=-1)/subRL (bf= -1/0/+1)/   \CL   CR旋转后结构subRL (bf=0)/      \parent     subR/   \      /   \CL  CR_L  CR_R  CR

和左右双旋相反:

	void RotateRL(Node* parent){// 1. 获取相关节点Node* subR = parent->_right;Node* subRL = subR->_left;	// subR的左孩子(subRL,即失衡的中间节点)int bf = subRL->_bf;		// 保存subRL的原始平衡因子// 2. 双旋转操作RotateR(parent->_right);	// 先对subR进行右旋(将subRL提升为subR的位置)RotateL(parent);			// 再对parent进行左旋(将subRL提升为根)// 3. 根据subRL的原始平衡因子调整平衡因子if (bf == 0){subR->_bf = 0;subRL->_bf = 0;parent->_bf = 0;}else if (bf == 1){subR->_bf = 0;subRL->_bf = 0;parent->_bf = -1;}else if (bf == -1){subR->_bf = 1;subRL->_bf = 0;parent->_bf = 0;}else{assert(false);}}

2.4 AVL 树的查找

通过二叉搜索树的规则进行查找就是了,这个不难

	Node* Find(const K& key){Node* cur = _root;while (cur){if (cur->_kv.first < key){cur = cur->_right;}else if (cur->_kv.first > key){cur = cur->_left;}else{return cur;}}return nullptr;}

2.5 AVL 树平衡检测

我们实现的AVL树是否合格,我们通过检查左右子树高度差的的程序进行反向验证,同时检查一下结点的平衡因子更新是否出现了问题。

这里简单提一下,因为 AVL 树是棵树,所以我们常见的遍历方式是通过递归调用,而这种 递归调用 直接暴露给用户显然不太合适,所以我们这里选择暴露一个公有接口,提供简洁的访问入口,隐藏内部实现细节,再通过私有辅助函数去完成内部实现细节。这种写法属于 包装器模式 的一种应用,有兴趣的自己去搜下。

class AVLTree
{
public:int Height(){return _Height(_root);}bool IsBalanceTree(){return _IsBalanceTree(_root);}
private:int _Height(Node* root){if (root == nullptr)return 0;int leftHeight = _Height(root->_left);int rightHeight = _Height(root->_right);return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;}bool _IsBalanceTree(Node* root){// 空树也是AVL树if (nullptr == root)return true;// 计算pRoot结点的平衡因子:即pRoot左右子树的高度差int leftHeight = _Height(root->_left);int rightHeight = _Height(root->_right);int diff = rightHeight - leftHeight;// 如果计算出的平衡因子与pRoot的平衡因子不相等,或者// pRoot平衡因子的绝对值超过1,则一定不是AVL树if (abs(diff) >= 2){cout << root->_kv.first << "高度差异常" << endl;return false;}if (root->_bf != diff){cout << root->_kv.first << "平衡因子异常" << endl;return false;}

相关文章:

【数据结构】AVL树的实现

文章目录 1. AVL 的概念2. AVL 树的实现2.1 AVL 树的结构2.2 AVL 树的插入2.2.1 AVL 树插入一个值的大致过程2.2.2 平衡因子更新 2.3 旋转2.3.1 旋转的原则2.3.2 右单旋2.3.3 左单旋2.3.4 左右双旋2.3.5 右左双选 2.4 AVL 树的查找2.5 AVL 树平衡检测 1. AVL 的概念 AVL树是最…...

基于Zynq SDK的LWIP UDP组播开发实战指南

一、为什么选择LWIP组播? 在工业控制、智能安防、物联网等领域,一对多的高效数据传输需求日益增长。Zynq-7000系列SoC凭借其ARM+FPGA的独特架构,结合LWIP轻量级网络协议栈,成为嵌入式网络开发的理想选择。本文将带您实现: LWIP组播配置全流程动态组播组切换技术零拷贝数据…...

【esp32 控制台】-命令

文章目录 1 esp32控制台简介2 控制台命令编程2.1 控制台配置交互设备初始化控制台初始化等待命令输入 2.2 命令实现2.2.1 命令注册 踩坑记录 1 esp32控制台简介 可以通过idf.py monitor调出idf的控制台&#xff0c;结束控制台用ctrl ]。 esp32的控制台就像linux中的shell一样…...

DApp开发全流程解析:模式设计、功能参考与合约管理实践

DApp开发全流程解析&#xff1a;模式设计、功能参考与合约管理实践 引言&#xff1a;Web3.0时代的DApp开发范式 随着区块链技术的成熟&#xff0c;DApp&#xff08;去中心化应用&#xff09;已成为Web3.0生态的核心载体。截至2025年&#xff0c;全球DApp数量突破10万&#xf…...

I/O多路复用:poll与epoll

一、select/poll与epoll对比 核心区别 特性select/pollepoll内核数据结构数组&#xff08;线性结构&#xff09;红黑树&#xff08;存储监听的fd&#xff09;内存拷贝每次调用需将fd列表从用户态拷贝到内核态仅在注册fd时拷贝一次&#xff08;epoll_ctl&#xff09;内核事件检…...

【调制识别】PGD攻击中参数的含义

在PGD&#xff08;Projected Gradient Descent&#xff09;对抗攻击中&#xff0c;代码如下&#xff1a; # 定义PGD对抗样本生成类 class AttackPGD(nn.Module): def __init__(self, model, config):super(AttackPGD, self).__init__()self.model model …...

设备数据看板助力自动化工厂实现生产智能精细化管理

工厂数字化转型需要实现自动化设备生产现场可视化、设备系统间的互联互通&#xff0c;以及数据的智能决策。然而&#xff0c;当前许多制造企业仍面临着传统单机设备同质化严重、数字化服务能力不足、售后成本高企、系统集成效率低下等挑战。企业如何通过自动化装备看板和实时数…...

单点登录是是什么?具体流程是什么?

SSO⼀般都需要⼀个独⽴的认证中⼼&#xff08;passport&#xff09;&#xff0c;⼦系统的登录均得通过passport&#xff0c;⼦系统本⾝将不参与登录操作&#xff0c;当⼀个系统成功登录以后&#xff0c;passport将会颁发⼀个令牌给各个⼦系统&#xff0c;⼦系统可以拿着令牌会获…...

什么业务需要用到waf

Web应用防火墙&#xff08;Web Application Firewall&#xff0c;简称WAF&#xff09;主要用于保护Web应用程序免受各种网络攻击&#xff0c;以下是需要用到WAF的业务类型及具体场景&#xff1a; 一、电子商务业务 业务特点&#xff1a;涉及用户注册、登录、支付等敏感操作&a…...

java中的Servlet4.x详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 Servlet 4.x 是 Java EE 8&#xff08;现 Jakarta EE&#xff09;规范的一部分&#xff0c;于 2017 年正式发布。作为 Servlet 技术的重大更…...

## Docker 中 Elasticsearch 启动失败:日志文件权限问题排查与解决

好的&#xff0c;这是一份关于你遇到的 Docker Elasticsearch 启动报错问题的笔记&#xff0c;包含问题描述、我的分析判断以及最终的解决方案&#xff0c;适合用于整理成文章。 Docker 中 Elasticsearch 启动失败&#xff1a;日志文件权限问题排查与解决 在使用 Docker部署 E…...

JavaScript:PC端特效--缓动动画

一、缓动效果原理 缓动动画就是让元素运动速度有所变化&#xff0c;最常见的就是让元素慢慢停下来 思路&#xff1a; 让盒子每次移动的距离慢慢变小&#xff0c;速度就会慢慢降下来核心算法&#xff1a;&#xff08;目标值-现在位置&#xff09;/10作为每次移动距离的步长停…...

【深度学习新浪潮】什么是多模态大模型?

多模态大模型是人工智能领域的前沿技术方向,它融合了多种数据模态(如文本、图像、语音、视频、传感器数据等),并通过大规模参数模型实现跨模态的联合理解与生成。简单来说,这类模型就像人类一样,能同时“看”“听”“读”“说”,并将不同信息关联起来,完成复杂任务。 …...

C++23 std::mdspan:多维数组处理新利器

文章目录 引言C23简介std::mdspan的定义与特点定义特点 std::mdspan的优势零成本抽象的多维数据访问减少内存开销提高代码灵活性 std::mdspan的应用场景科学计算图形学 相关提案示例代码使用动态扩展使用静态和动态扩展 总结 引言 在C的发展历程中&#xff0c;每一个新版本都带…...

09、底层注解-@Import导入组件

09、底层注解-Import导入组件 Import是Spring框架中的一个注解&#xff0c;用于将组件导入到Spring的应用上下文中。以下是Import注解的详细介绍&#xff1a; #### 基本用法 - **导入配置类** java Configuration public class MainConfig { // 配置内容 } Configuration Impo…...

码蹄集——N是什么、棋盘

MT1223 N是什么 给定一系列数字3、10、21、36…&#xff0c;输入正整数N&#xff0c;输出上述序列的第N个值。从N1开始计数。 格式 输入格式&#xff1a;输入正整数N 输出格式&#xff1a;输出整型 样例 1 输入&#xff1a;5 输出&#xff1a;55 备注&#xff1a;N小于…...

C++中聚合类(Aggregate Class)知识详解和注意事项

一、聚合类&#xff08;Aggregate Class&#xff09;概念 聚合&#xff08;Aggregate&#xff09; 是 C 中一类特殊的类类型&#xff0c;无用户自定义构造函数、无私有或受保护非静态数据成员、无虚函数、无基类&#xff08;C11 起基类必须也是聚合且无私有/受保护成员&#x…...

python打卡day30

模块和库的导入 知识点回顾&#xff1a; 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑&#xff1a;找到根目录&#xff08;python解释器的目录和终端的目录不一致&#xff09; 作业&#xff1a;自己新建几个不同路径文件尝试下如何导入 python的学习就像…...

PostGIS实现栅格数据导出图片标准格式【ST_AsGDALRaster】

ST_AsGDALRaster 函数应用详解&#xff1a;将栅格数据导出为标准图片格式 [文章目录] 一、函数概述 二、函数参数详解 三、关键功能示例 四、GDAL 选项配置指南 五、性能优化建议 六、注意事项与限制 七、应用场景 八、总结 一、函数概述 ST_AsGDALRaster是PostGIS中…...

4.6 sys模块

sys --- 仅作了解 面试之前冲击一下 python的垃圾回收机制 import sys # 1. api_version : 获取python的内部版本号 print(sys.api_version) #1013 # 2. copyright: 获取cpython的版本 print(sys.copyright) #3.getfilesystemencoding() getdefaultencoding():获…...

「HHT(希尔伯特黄变换)——ECG信号处理-第十三课」2025年5月19日

一、引言 心电信号&#xff08;ECG&#xff09;是反映心脏电活动的重要生理信号&#xff0c;其特征提取对于心脏疾病的诊断和监测具有关键意义。Hilbert - Huang Transform&#xff08;HHT&#xff09;作为一种强大的信号处理工具&#xff0c;在心电信号特征提取领域得到了广泛…...

枪机定焦系统的自动控制装置

枪机定焦系统&#xff0c;作为一种监控设备&#xff0c;通常被广泛应用于各种需要高清、远距离监控的场合。该系统的主要特点是其镜头焦距固定&#xff0c;不能手动或自动调节&#xff0c;从而确保了监控画面的稳定性和清晰度。当提到枪机定焦系统采用自动功能时&#xff0c;可…...

【Unity】Unity中将字典序列化

Unity中将字典序列化&#xff0c;在预制体上能够看到字典的内容&#xff0c;也可以直接在预制体上拖拽给字典赋值 直接上代码 using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine;public class SerializableD…...

VTK|箱体切割器

文章目录 效果实现类头文件实现类源文件如何调用项目git链接 效果 实现类头文件 /*** file BoxClipperController.h* brief 该头文件定义了 BoxClipperController 类&#xff0c;用于管理基于盒子的网格数据裁剪操作。* details 该类提供了使用 vtkBoxWidget 对网格数据进行裁…...

CS50x 01 c

1 getchar() 在 C 语言里&#xff0c;getchar()是一个十分常用的函数&#xff0c;其功能是从标准输入&#xff08;一般指键盘&#xff09;读取单个字符。下面为你详细介绍它的用法。 基本语法 getchar()函数的原型定义在<stdio.h>头文件中&#xff0c;语法形式如下&am…...

确保高质量的音视频通话,如何最大化利用视频带宽

在当今数字时代&#xff0c;音视频内容随处可见&#xff0c;对于开发者来说&#xff0c;理解互联网带宽变得至关重要。我们的在线体验质量&#xff0c;无论是观看高清电影还是演唱会直播&#xff0c;都严重依赖于互联网带宽的概念。在本文中&#xff0c;我们将揭示视频带宽的复…...

@RequestParam 和 @RequestBody、HttpServletrequest 与HttpServletResponse

在Java Web开发中&#xff0c;RequestParam、RequestBody、HttpServletRequest 和 HttpServletResponse 是常用的组件&#xff0c;它们用于处理HTTP请求和响应。下面分别介绍它们的使用场景和使用方法&#xff1a; 1. RequestParam RequestParam 是Spring MVC框架中的注解&am…...

HashMap 的特点及应用场景

一、HashMap 核心特点 1. 基本特性 键值对存储&#xff1a;基于 Map 接口实现&#xff0c;存储 Key-Value 对 允许 null 键/值&#xff1a;可以有一个 null 键和多个 null 值 非线程安全&#xff1a;多线程环境下需要额外的同步措施 无序存储&#xff1a;不保证元素的插入顺…...

day30 python 模块、包与库的高效使用指南

目录 一、Python库的分类与适用场景 表格 1.1 基础工具库 1.2 科学计算库 1.3 数据分析库 1.4 Web开发库 1.5 机器学习库 1.6 自动化脚本库 1.7 网络爬虫库 二、模块与包的导入方式 2.1 标准导入 2.2 从模块中导入特定项 2.3 非标准导入&#xff08;不推荐&#x…...

JVM核心配置参数详解与调优指南

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 引言 Java虚拟机&#xff08;JVM&#xff09;的配置参数直接影响应用程序的性能、稳定性和资源利用率。合理配置参数能够显著提升吞吐量、降低延迟并避免内存…...

python打卡第30天

知识点回顾&#xff1a; 一&#xff0c;导入官方库的三种手段。 使用 import 直接导入整个模块 import module_name 使用 from ... import ... 导入特定功能 from module_name import function_name 使用 as 关键字重命名模块或功能 import module_name as alias # 或 from mod…...

数据要素及征信公司数据要素实践

数据要素及征信公司数据要素实践 1.数据要素的定义与核心特征2.征信公司应用数据要素的实践路径3.总结1.数据要素的定义与核心特征 数据要素是数字经济时代的新型生产要素,指以电子形式存在、通过计算方式参与生产经营活动并创造价值的数据资源。 其核心特征包括: 新型生产…...

耗时十分钟,做了一个 uniapp 灵感泡泡机

最近&#xff0c;我用 UniApp 搭配 CodeBuddy 实现了一个充满童话感的小应用&#xff0c;名叫 IdeaBubbles&#xff08;灵感泡泡机&#xff09;。它是一个单页 WebApp&#xff0c;用来记录那些转瞬即逝的灵感时刻。整个界面以梦幻气泡和彩虹玻璃拟态为主题&#xff0c;视觉效果…...

《Head First 设计模式》第二章 - 笔记

本书是本人写的设计模式的笔记&#xff0c;写下核心要点&#xff0c;如果你掌握过设计模式&#xff0c;想快速阅读本书内容&#xff0c;这个笔记适合你阅读。如果你是新手&#xff0c;有 java 基础和 oo 设计原则基础&#xff0c;你适合跟我一样从零阅读本书。 第一章 观察者模…...

matlab绘制光学传递函数mtf曲线

在 MATLAB 中绘制光学系统的光学传递函数&#xff08;Modulation Transfer Function&#xff0c;MTF&#xff09;曲线可以通过以下步骤实现。MTF 是描述光学系统对物体细节的传递能力的函数&#xff0c;通常用于分析成像系统的性能。 假设我们有一个理想的光学系统&#xff0c…...

贵州某建筑物挡墙自动化监测

1. 项目简介 某建筑物位于贵州省某县城区内&#xff0c;靠近县城主干道&#xff0c;周边配套学校、医院、商贸城。建筑物临近凤凰湖、芙蓉江等水系&#xff0c;主打“湖景生态宜居”。改建筑物总占地面积&#xff1a;约5.3万平方米&#xff1b;总建筑面积&#xff1a;约15万平…...

自定义协议与序列化

前言 书接上回&#xff0c;我们上一篇提到了协议并且我们草率的写了一个协议&#xff0c;然后又对TCP的R和W留了一个伏笔&#xff0c;我们今天彻底做个了断。 UDP是面向数据报的&#xff0c;它要么不读&#xff0c;要么就是一次读完的&#xff0c;所以不存在数据断断续续的问…...

MySQL中的Change Buffer是什么,它有什么作用?

MySQL 中的 Change Buffer&#xff08;更改缓冲区&#xff09;是 InnoDB 存储引擎使用的一种特殊数据结构&#xff0c;主要用于优化对二级索引&#xff08;secondary indexes&#xff09;的写操作性能。 它的核心作用是&#xff1a; 当对表进行 INSERT、UPDATE 或 DELETE 操作…...

Ubuntu 20.04之Docker安装ES7.17.14和Kibana7.17.14

你需要已经安装如下运行环境: Ubuntu 20.04 docker 28 docker-compose 1.25 一、手动拉取镜像 docker pull docker.elastic.co/kibana/kibana:7.17.14docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.14 或者手动导入镜像 docker load -i es7.17.14.ta…...

ThreadLocal作一个缓存工具类

1、工具类 import java.util.HashMap; import java.util.Map;public class ThreadLocalUtil {// 使用Map存储多类型数据private static final ThreadLocal<Map<String, Object>> CONTEXT_HOLDER new ThreadLocal<>();// 存储数据public static void set(Str…...

DeepSeek在旅游行业的智能化革命

2025年,从贵州全域智慧旅游平台的行程规划革命,到黄山景区"AI旅行助手"的实时服务升级,再到宁夏"游宁AI"的全域智能导览,DeepSeek通过技术创新与行业场景的深度融合,正在重新定义"智慧旅游"的内涵。这场变革不仅体现在效率提升层面,更通过…...

说一下响应状态码有哪些?

HTTP响应状态码分类(RFC 7231标准) 1. 1xx(信息类) 临时响应,表示请求已被接收,需要继续处理 100 Continue:客户端应继续发送请求体 101 Switching Protocols:服务器同意升级协议(如WebSocket) 102 Processing(WebDAV):服务器正在处理但未完成 2. 2xx(成功类)…...

ABAP实战案例--获取当前数据由哪个用户锁住

1、业务场景&#xff1a; A用户正在打开订单&#xff0c;订单已上锁&#xff1b;B用户打开时只允许查看并提醒由哪个用户正在操作该笔订单。 2、函数使用&#xff1a;ENQUEUE_READ 代码示例&#xff1a; DATA:LV_MESSAGE TYPE SY-MSGV1,LV_UNAME TYPE UNAME.DATA:LV_GARG …...

CSS 选择器入门

一、CSS 选择器基础&#xff1a;快速掌握核心概念 什么是选择器&#xff1f; CSS 选择器就像 “网页元素的遥控器”&#xff0c;用于定位 HTML 中的特定元素并应用样式。 /* 结构&#xff1a;选择器 { 属性: 值; } */ p { color: red; } /* 选择所有<p>元素&#xff0c;…...

【深度学习新浪潮】如何入门人工智能?

入门人工智能(AI)需要结合数学基础、编程技能、机器学习理论和实践项目,逐步深入。以下是一个系统的学习路径,适合零基础或初学者参考: 一、打好基础:数学与编程 1. 数学基础(关键) AI的核心依赖数学,尤其是以下领域: 线性代数:向量、矩阵运算、特征分解等(用于…...

软件工程第六章-详细设计

文章目录 程序流程图PAD图N-S图(盒图)流图根据PDL创建流图把程序流程图映射到流图 程序流程图 PAD图 N-S图(盒图) 流图 根据PDL创建流图 把程序流程图映射到流图...

Profinet转Modbus TCP协议转换技术,打通能耗监控‘最后一公里’

在工业自动化领域&#xff0c;Profinet与Modbus TCP是两种广泛使用的通讯协议。Profinet通常用于实时性要求较高的工业控制系统&#xff0c;而Modbus TCP则因其简单、开放的特性广泛应用于各类设备的通信。然而&#xff0c;由于两者在技术规范上的差异&#xff0c;直接的互联互…...

C++:因子问题

【描述】 任给两个正整数N、M&#xff0c;求一个最小的正整数a&#xff0c;使得a和(M-a)都是N的因子。 【输入】 包括两个整数N、M。N不超过1,000,000。 【输出】 输出一个整数a&#xff0c;表示结果。如果某个案例中满足条件的正整数不存在&#xff0c;则在对应行输出-1 【样例…...

SAP系统的委外业务是什么?委外采购(标准委外)与工序外协的区别有哪些?

【SAP系统研究】 #SAP #委外 #外包 #代工 委外业务是很常见的业务类型。 企业生产过程中,会在自制生产之外,产生委外加工业务,也称之为外包或者代工。还有一些企业,自己只负责设计、市场等业务,而将生产加工环节交给其他公司。 一、委外产生的原因 有的企业由于环评、…...

小乌龟git中的推送账户、作者账户信息修改

文章目录 修改git文档作者信息修改git推送用户信息参考文献 修改git文档作者信息 小乌龟中的用户信息为&#xff1a;作者信息&#xff0c;并非推送用户。 上边用户信息&#xff0c;修改的是文件的作者信息。如果想要修改git服务中记录的推送用户信息需要修改推送用户信息。 …...