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

c++(AVL树及其实现)

一、AVL树的概念

AVL树是最先发明的自平衡⼆叉查找树,AVL是⼀颗空树,或者具备下列性质的⼆叉搜索树:它的

左右子树都是AV树,且左右子树的高度差的绝对值不超过1。AVL树是⼀颗高度平衡搜索⼆叉树,

通过控制高度差去控制平衡。

AVL树得名于它的发明者G. M. Adelson-Velsky和E. M. Landis是两个前苏联的科学家,他们在1962

年的论文《An algorithm for the organization of information》中发表了它。

AVL树实现这里我们引入⼀个平衡因子(balance factor)的概念,每个结点都有⼀个平衡因子,任何

结点的平衡因子等于右子树的高度减去左子树的高度,也就是说任何结点的平衡因子等于0/1/-1,

AVL树并不是必须要平衡因子,但是有了平衡因子可以更方便我们去进行观察和控制树是否平衡,

就像⼀个风向标⼀样。

思考⼀下为什么AVL树是高度平衡搜索⼆叉树,要求高度差不超过1,而不是高度差是0呢?0不是更

好的平衡吗?画画图分析我们发现,不是不想这样设计,而是有些情况是做不到高度差是0的。⽐

如⼀棵树是2个结点,4个结点等情况下,高度差最好就是1,无法作为高度差是0

AVL树整体结点数量和分布和完全⼆叉树类似,高度可以控制在 ,那么增删查改的效率也可

以控制在 ,相比⼆叉搜索树有了本质的提升。

在这里插入图片描述

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二、AVL树的实现

1、AVL树的结构

#pragma once
#include<iostream>
using namespace std;
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){}
};
template<class K, class V>
class AVLTree
{typedef AVLTreeNode<K, V> Node;
public:
private:Node * _root = nullptr;
};

2、插入

  1. 插入一个值按⼆叉搜索树规则进行插入。

  2. 新增结点以后,只会影响祖先结点的高度,也就是可能会影响部分祖先结点的平衡因子,所以更新

从新增结点->根结点路径上的平衡因子,实际中最坏情况下要更新到根,有些情况更新到中间就可

以停止了,具体情况我们下面再详细分析。

  1. 更新平衡因子过程中没有出现问题,则插入结束

  2. 更新平衡因子过程中出现不平衡,对不平衡子树旋转,旋转后本质调平衡的同时,本质降低了子树

的高度,不会再影响上⼀层,所以插入结束。

3、平衡因子更新

更新原则

平衡因子 = 右子树高度-左子树高度

只有子树高度变化才会影响当前结点平衡因子。

插入结点,会增加高度,所以新增结点在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,会影响arent的父亲结点的平衡因子,所以要继续向上

更新。

更新后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->_left = cur;}else{parent->_right = cur;}//更新平衡因子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){//选转break;}}}

4、旋转

a、右单旋

本图1展⽰的是10为根的树,有a/b/c抽象为三棵高度为h的子树(h>=0),a/b/c均符合AVL树的要

求。10可能是整棵树的根,也可能是⼀个整棵树中局部的子树的根。这里a/b/c是高度为h的子树,

是⼀种概括抽象表示,他代表了所有右单旋的场景,实际右单旋形态有很多种,具体图2/图3/图4/

图5进行了详细描述。

在a子树中插入⼀个新结点,导致a子树的高度从h变成h+1,不断向上更新平衡因子,导致10的平

衡因子从-1变成-2,10为根的树左右高度差超过1,违反平衡规则。10为根的树左边太高了,需要

往右边旋转,控制两棵树的平衡。

旋转核心步骤,因为5 < b子树的值 < 10,将b变成10的左子树,10变成5的右子树,5变成这棵树新

的根,符合搜索树的规则,控制了平衡,同时这棵的高度恢复到了插入之前的h+2,符合旋转原

则。如果插入之前10整棵树的⼀个局部子树,旋转后不会再影响上⼀层,插入结束了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码:

void RotateR(Node* parent)
{Node* Pparent = parent->_parent;Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;// 需要注意除了要修改孩子指针指向,还是修改父亲if (subLR)//防止对空指针解引用 subLR->_parent = parent;subL->_right = parent;parent->_parent = subL;if (Pparent == nullptr)//parent是根时{_root = subL;subL->_parent = nullptr;}else{if (parent == parentParent->_left){parentParent->_left = subL;}else{parentParent->_right = subL;}subL->_parent = parentParent;}//更新平衡因子parent->_bf = subL->_bf = 0;
}

b、左单旋

本图6展示的是10为根的树,有a/b/c抽象为三棵高度为h的子树(h>=0),a/b/c均符合AVL树的要

求。10可能是整棵树的根,也可能是⼀个整棵树中局部的子树的根。这里a/b/c是高度为h的子树,

是⼀种概括抽象表示,他代表了所有右单旋的场景,实际右单旋形态有很多种,具体跟上⾯左旋类

似。

在a子树中插入⼀个新结点,导致a子树的高度从h变成h+1,不断向上更新平衡因子,导致10的平

衡因子从1变成2,10为根的树左右高度差超过1,违反平衡规则。10为根的树右边太高了,需要往

左边旋转,控制两棵树的平衡。

旋转核心步骤,因为10 < b子树的值 < 15,将b变成10的右子树,10变成15的左子树,15变成这棵

树新的根,符合搜索树的规则,控制了平衡,同时这棵的高度恢复到了插入之前的h+2,符合旋转

原则。如果插入之前10整棵树的⼀个局部子树,旋转后不会再影响上⼀层,插入结束了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码:

void RotateL(Node* parent)
{Node* Pparent = parent->_parent;Node* subR = parent->_right;Node* subRL = subL->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;parent->_parent = subR;if (Pparent == nullptr)//parent是根时{_root = subR;subR->_parent = nullptr;}else{if (parent == parentParent->_left){parentParent->_left = subR;}else{parentParent->_right = subR;}subR->_parent = parentParent;}parent->_bf = subR->_bf = 0;
}

c、左右双旋

通过图7和图8可以看到,左边高时,如果插入位置不是在a子树,而是插入在b子树,b子树高度从h变

成h+1,引发旋转,右单旋无法解决问题,右单旋后,我们的树依旧不平衡。右单旋解决的纯粹的左边

高,但是插入在b子树中,10为跟的子树不再是单纯的左边高,对于10是左边高,但是对于5是右边

高,需要用两次旋转才能解决,以5为旋转点进行⼀个左单旋,以10为旋转点进行⼀个右单旋,这棵树

这棵树就平衡了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图7和图8分别为左右双旋中h=0和h=1具体场景分析,下面我们将a/b/c子树抽象为高度h的AVL

子树进行分析,另外我们需要把b子树的细节进⼀步展开为8和左子树高度为h-1的e和f子树,因为

我们要对b的父亲5为旋转点进行左单旋,左单旋需要动b树中的左子树。b子树中新增结点的位置

不同,平衡因子更新的细节也不同,通过观察8的平衡因子不同,这里我们要分三个场景讨论。

场景1:h >= 1时,新增结点插⼊在e子树,e子树高度从h-1变为h并不断更新8->5->10平衡因子,

引发旋转,其中8的平衡因子为-1,旋转后8和5平衡因子为0,10平衡因子为1。

场景2:h >= 1时,新增结点插⼊在f子树,f子树高度从h-1变为h并不断更新8->5->10平衡因子,引

发旋转,其中8的平衡因子为1,旋转后8和10平衡因子为0,5平衡因子为-1。

场景3:h == 0时,a/b/c都是空树,b⾃⼰就是⼀个新增结点,不断更新5->10平衡因子,引发旋

转,其中8的平衡因子为0,旋转后8和10和5平衡因子均为0。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

void RotateLR(Node* parent)
{Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;//根据subLR的平衡因子判断RotateL(parent->_left);RotateR(parent);if (bf == 0){subL->_bf = 0;subLR->_bf = 0;parent->_bf = 0;}else if (bf == -1){subL->_bf = 0;subLR->_bf = 0;}else if (bf == 1)parent->_bf = 1;{subL->_bf = -1;subLR->_bf = 0;parent->_bf = 0;}else{assert(false);}
}

d、右左双旋

跟左右双旋类似,下⾯我们将a/b/c子树抽象为⾼度h的AVL子树进⾏分析,另外我们需要把b子树的

细节进⼀步展开为12和左子树⾼度为h-1的e和f子树,因为我们要对b的⽗亲15为旋转点进⾏右单

旋,右单旋需要动b树中的右子树。b子树中新增结点的位置不同,平衡因子更新的细节也不同,通

过观察12的平衡因子不同,这⾥我们要分三个场景讨论。

场景1:h >= 1时,新增结点插⼊在e子树,e子树⾼度从h-1变为h并不断更新12->15->10平衡因

子,引发旋转,其中12的平衡因子为-1,旋转后10和12平衡因子为0,15平衡因子为1。

场景2:h >= 1时,新增结点插⼊在f子树,f子树⾼度从h-1变为h并不断更新12->15->10平衡因子,

引发旋转,其中12的平衡因子为1,旋转后15和12平衡因子为0,10平衡因子为-1。•

场景3:h == 0时,a/b/c都是空树,b自己就是⼀个新增结点,不断更新15->10平衡因子,引发旋

转,其中12的平衡因子为0,旋转后10和12和15平衡因子均为0。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

void RotateRL(Node* parent)
{Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;RotateR(parent->_right);RotateL(parent);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);}
}

三、整体代码

#pragma once
#include<iostream>
using namespace std;
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){}
};
template<class K, class V>
class AVLTree
{typedef AVLTreeNode<K, V> Node;
public: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;if (parent->_kv->first > kv.first){parent->_left = cur;}else{parent->_right = cur;}//更新平衡因子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){RotateL(parent);}else if (parent->_bf == 2 && cur->_bf == 1){RotateR(parent);}else if (parent->_bf == -2 && cur->_bf == 1){RotateLR(parent);}else{RotateRL(parent);}break;}}}void RotateR(Node* parent){Node* Pparent = parent->_parent;Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;// 需要注意除了要修改孩⼦指针指向,还是修改⽗亲if (subLR)//防止对空指针解引用 subLR->_parent = parent;subL->_right = parent;parent->_parent = subL;if (Pparent == nullptr)//parent是根时{_root = subL;subL->_parent = nullptr;}else{if (parent == parentParent->_left){parentParent->_left = subL;}else{parentParent->_right = subL;}subL->_parent = parentParent;}//更新平衡因子parent->_bf = subL->_bf = 0;}void RotateL(Node* parent){Node* Pparent = parent->_parent;Node* subR = parent->_right;Node* subRL = subL->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;parent->_parent = subR;if (Pparent == nullptr)//parent是根时{_root = subR;subR->_parent = nullptr;}else{if (parent == parentParent->_left){parentParent->_left = subR;}else{parentParent->_right = subR;}subR->_parent = parentParent;}parent->_bf = subR->_bf = 0;}void RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;//根据subLR的平衡因子判断RotateL(parent->_left);RotateR(parent);if (bf == 0){subL->_bf = 0;subLR->_bf = 0;parent->_bf = 0;}else if (bf == -1){subL->_bf = 0;subLR->_bf = 0;}else if (bf == 1)parent->_bf = 1;{subL->_bf = -1;subLR->_bf = 0;parent->_bf = 0;}else{assert(false);}}void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;RotateR(parent->_right);RotateL(parent);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);}}
private:Node * _root = nullptr;
};

相关文章:

c++(AVL树及其实现)

一、AVL树的概念 AVL树是最先发明的自平衡⼆叉查找树&#xff0c;AVL是⼀颗空树&#xff0c;或者具备下列性质的⼆叉搜索树&#xff1a;它的 左右子树都是AV树&#xff0c;且左右子树的高度差的绝对值不超过1。AVL树是⼀颗高度平衡搜索⼆叉树&#xff0c; 通过控制高度差去控…...

Cesium GIS项目关于湖泊识别与提取的实现

1. 引言 项目背景 随着遥感技术的发展,地理信息系统的应用越来越广泛。本项目旨在开发一个基于Cesium的地理信息系统,利用深度学习技术自动识别并显示湖泊的位置。 目标与意义 通过自动化处理大量遥感影像数据,提高湖泊监测的效率和准确性,为水资源管理和环境保护提供支…...

两个圆形 一个z里面一个z外面,z里面的大,颜色不同 html

两个圆形 一个z里面一个z外面&#xff0c;z里面的大&#xff0c;颜色不同 html <!DOCTYPE html> <html> <head> <style> .outer-circle {width: 150px;height: 150px;border-radius: 50%;background-color: #ff9999; /* 外圆的颜色 */position: relat…...

【Power Query】M函数-table

M函数-table 添加列&#xff08;AddColumn&#xff09;&#xff1a;条件语句&#xff08;If..then..else&#xff09;&#xff1a;容错语句&#xff08;try..otherwise&#xff09;&#xff1a; 排序&#xff08;ReorderColumns&#xff09;&#xff1a;筛选&#xff08;Selec…...

uni-app 封装websocket 心跳检测,开箱即用

class websocketUtils {constructor(url, needbeat, options {}) {this.needbeat needbeat;this.url url;this.options options;this.ws null;this.heartbeatInterval options.heartbeatInterval || 10000; // 心跳间隔&#xff0c;默认为10秒 this.reconnectInterval …...

ASP.NET Core8.0学习笔记(十九)——EF Core DbSet

一、DbSet概述 1.DbSet提供了通过DbContext对表进行查询操作的路径。DbSet对应的属性名称将默认映射为实体T的表名。 2.使用DbSet<T>进行查询的方法&#xff1a; (1)直接在DbContext中创建对应的DbSet<T>属性 (2)使用DbSet DbContext.Set<T>方法操作数据表。…...

Android Camera 预览角度和拍照保存图片角度相关

–基于Android R(11) 关于Camera Camera Framework 的架构 Android Camera Framework 是一个分层架构&#xff0c;由以下组件组成&#xff1a; HAL&#xff08;硬件抽象层&#xff09;: HAL 抽象底层相机硬件,提供与不同设备相机进行交互的标准接口.CameraService : Camera…...

新手如何使用Qt——方法使用

前言 那么这篇文章其实是我在使用Qt的过程当中呢&#xff0c;我发现在Qt使用过程中&#xff0c;在我理解信号和槽这个概念后&#xff0c;在编写槽函数数的时候&#xff0c;发现了自身存在的问题&#xff0c;我的难点是在于当我在编写槽函数的时候&#xff0c;我知道这个槽函数是…...

友元运算符重载函数

目录 1.定义友元运算符重载函数的语法形式 2.双目运算符重载 3.单目运算符重载 1.定义友元运算符重载函数的语法形式 &#xff08;1&#xff09;在类的内部&#xff0c;定义友元运算符重载函数的格式如下&#xff1a; friend 函数类型 operator 运算符&#xff08;形参表&a…...

从0开始实现es6 promise类

主要由基础实现和静态类的实现两部分组成。 1 基础实现&#xff08;不含静态类&#xff09; 1.1 使用类实现完成构造函数 实现代码如下&#xff0c;构造函数传入一个回调函数&#xff0c;定义resolve和reject函数&#xff0c;将两个函数作为参数执行回调函数。 // 1. 使用类实…...

XML 编码

XML 编码 XML&#xff08;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言。它由万维网联盟&#xff08;W3C&#xff09;开发&#xff0c;旨在提供一种标准的方式来结构化、存储和传输数据。XML的设计目标是既易于人类阅读&#xff0c;也易于机器解析。 XML的…...

AI周报(9.22-9.28)

AI应用-Siipet宠物沟通师 Siipet是一款由SiiPet公司推出的创新宠物行为分析相机&#xff0c;旨在通过尖端技术加深宠物与主人之间的情感联系。这款相机利用先进的AI算法&#xff0c;能够自动识别和分析家中宠物的行为&#xff0c;并提供定制化的护理建议。 SiiPet相机的核心功…...

基于RealSense D435相机实现手部姿态重定向

基于Intel RealSense D435相机和MediaPipe的手部姿态检测&#xff0c;进一步简单实现手部姿态与机器人末端的重定向&#xff0c;获取手部的6D坐标&#xff08;包括位置和姿态&#xff09;。 假设已经按照【基于 RealSenseD435i相机实现手部姿态检测】配置好所需的库和环境&…...

js中防抖 debounce 节流 throttle 原理 从0手动实现

1 防抖 高频触发事件时&#xff0c;执行损耗高的操作&#xff0c;连续触发过程中&#xff0c;只执行最后一次。 高频事件&#xff1a;input scroll resize等。损耗高&#xff1a;网络请求、dom操作。 实现防抖步骤&#xff1a;1.在回调函数中判断timer是否存在&#xff0c;存在…...

AIGC: 10 AI转文服务器的搭建过程记录

上图是台风席卷城市&#xff0c;现在企业的服务基本都是混合部署&#xff0c;云计算厂商的机房往往可以提供比较好的保护&#xff0c;一般在地下&#xff0c;扛多少级地震&#xff0c;扛多少级台风&#xff0c;而自建机房&#xff0c;往往写字楼经常停电&#xff0c;网络运营上…...

性能测试1初步使用Jmeter

当你看到这边文章的时候&#xff0c;详细你已经知道啥是性能测试&#xff0c;以及也听说过Jmeter了&#xff0c;所以不过多介绍&#xff0c;这里&#xff0c;只是帮助你快速的使用Jmeter来测试接口。 1获取安装包 官网下载地址&#xff1a;https://jmeter.apache.org/downloa…...

OpenGL ES 绘制一个三角形(2)

OpenGL ES 绘制一个三角形(2) 简述 本节我们基于Android系统&#xff0c;使用OpenGL ES来实现绘制一个三角形。在OpenGL ES里&#xff0c;三角形是一个基础图形&#xff0c;其他的图形都可以使用三角形拼接而成&#xff0c;所以我们就的案例就基于这个开始。 在Android系统中…...

QT----Creater14.0,qt5.15无法启动调试,Launching GDB Debugger报红

问题描述 使用QT Creater 14.0 和qt5.15,无法启动调试也没有报错,加载debugger报红 相关文件都有 解决方案 尝试重装QT,更换版本5.15.2,下载到文件夹,shift鼠标右键打开powershell输入 .\qt-online-installer-windows-x64-4.8.0.exe --mirror http://mirrors.ustc.edu.cn…...

初试React前端框架

文章目录 一、React概述二、React核心特性1、组件化设计2、虚拟DOM3、生态系统 三、实例操作1、准备工作2、创建项目结构3、启动项目4、编写React组件5、添加React样式6、运行项目&#xff0c;查看效果 四、实战小结 一、React概述 大家好&#xff0c;今天我们将一起探索React…...

华为OD机试真题---手机App防沉迷系统

题目概述 智能手机在方便我们生活的同时&#xff0c;也侵占了大量时间。手机App防沉迷系统旨在帮助用户合理规划手机App使用时间&#xff0c;确保在正确的时间做正确的事。系统的主要功能包括&#xff1a; 在一天24小时内&#xff0c;可注册每个App的允许使用时段。一个时段只…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...