【C++】——AVL树(详细解读)

news2024/11/15 20:52:48

目录

一  AVL树的概念

二  AVL树节点的定义

 三  AVL树的插入

1.先和搜索二叉树一样,去找插入的结点

2.插入的时候,需要更新平衡因子

3.确定平衡因子的改变,判断AVL树的改变

三  AVL树的旋转

左单旋

右单旋

右左双旋

左右双旋

四   ALV插入完整代码

五  总结


一  AVL树的概念

二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。

当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。

 

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

如果一棵二叉搜索树的高度是平衡的,它就是AVL树。如果它有n个结点,其高度可保持在O ( l o g N ) O(logN)O(logN),搜索时间复杂度也是O ( l o g N ) O(logN)O(logN)。
因为他接近完全二叉树

二  AVL树节点的定义

对于AVL的定义来说首先我们肯定是模板,然后我们的结构为三叉链,同时我们还需要一个平衡因子去平衡高度

template<class K,class V>
struct AVLTreeNode
{
	AVLTreeNode<K, V>* _left;
	AVLTreeNode<K, V>* _right;
	AVLTreeNode<K, V>* _parent;//三叉链
	pair<K, V> _kv;
	int _bf; //平衡因子

	AVLTreeNode(const pair<K, V>& kv)//构造函数
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _bf(0)
	{}
};

 三  AVL树的插入

注意,这里只是简单对AVL树的情况大概总结一下,细节还需要看下面的具体过程

1.先和搜索二叉树一样,去找插入的结点

2.插入的时候,需要更新平衡因子

3.确定平衡因子的改变,判断AVL树的改变

1找插入位置

  1. 待插入结点的key值比当前结点小就插入到该结点的左子树。
  2. 待插入结点的key值比当前结点大就插入到该结点的右子树。
  3. 待插入结点的key值与当前结点的key值相等就插入失败。

 那这样我们根据上面的规则就很好写出我们的代码了

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);

2.更新平衡因子

我们插入可能会导致不平衡,这个时候我们就需要旋转去解决问题

 像上面的情况就不需要旋转去解决,因为子树的高度并没有变化,这里子树指的是

但是如果子树高度变化了,那么就需要去往上面更新

但是像上面这种,就会引发旋转,才能维持平衡,因为8的平衡因子为2已经破坏了平衡

1.父亲结点的平衡因子更新后为0,则不需要往上面更新

2.父亲结点的平衡因子更新后为1或者-1,则必须往上更新

3.父亲结点的平衡因子更新后为2或者-2,则需要旋转处理

3.判断AVL树的改变

如果父亲结点的平衡因子更新后为2或者-2,则需要旋转处理

到底要怎么旋转需要根据结点之间平衡因子的改变来判断

 对于下面这种情况来说,在

9 :parent结点

15:cur结点

这里 parent的平衡因子为2,cur的平衡因子为1; 

上图就是一个典型的左单旋,因为右边单纯高,左边单纯低,所以这里单纯的左单旋就行

如果反过来就是一个右单旋

对右单旋来说就是parent的平衡因子为-2,cur的平衡因子为-1;

还有就是左右双旋和右左双旋

  1. 当parent的平衡因子为-2,cur的平衡因子为1时,进行左右双旋。
  2. 当parent的平衡因子为2,cur的平衡因子为-1时,进行右左双旋。

总结来说就是

  1. 当parent的平衡因子为-2,cur的平衡因子为-1时,进行右单旋。
  2. 当parent的平衡因子为-2,cur的平衡因子为1时,进行左右双旋。
  3. 当parent的平衡因子为2,cur的平衡因子为-1时,进行右左双旋。
  4. 当parent的平衡因子为2,cur的平衡因子为1时,进行左单旋。

三  AVL树的旋转

左单旋

由上图可知:在插入之前树是一颗AVL树,而插入新结点之后,T的左右子树高度差的绝对值不再 < 1,此时AVL树的平衡性被破坏,我们要对其进行旋转。

左单旋步骤:

  • T向左旋转成为R的左结点
  • R的左节点Y放到T的右孩子上

根据上面的动图我们就可以很清楚去确定是怎么去操作的

 如果上面还是有点不理解,那么下面就看看抽象图

这里我们假设 30 为parent,60为subR, b为subRL

所有这里文字的解释就是

  1. 让subR的左子树作为parent的右子树。
  2. 让parent作为subR的左子树。
  3. 让subR作为整个子树的根。
  4. 更新平衡因子。

这里不用担心旋转以后会破化二叉搜索树的性质,因为:

  1. subR的左子树当中结点的值本身就比parent的值大,因此可以作为parent的右子树。
  2. parent及其左子树当中结点的值本身就比subR的值小,因此可以作为subR的左子树。

代码理解:

void RotateL(Node* parent)
	{
		Node* subR = parent->_right;//这里先进行旋转
		Node* subRL = subR->_left;

		parent->_right = subRL;//这里旋转已经完成,进行关系的变化
		subR->left = parent;

		Node* parentparent = parent->_parent;//可能这棵树只是一颗子树,所以要保留一下上一个结点
		parent->_parent = subR;
		if (subRL)//这里可能subRL是空,所以要特判
			subRL->_parent = parent;

		if (_root == parent)//如果是根那就不用parentparent了,直接变化关系就行
		{
			subR = _root;
			subR->_parent = nullptr;
		}
		else//如果不是根,只是一个子树,那就得看看是在parentparent的左还是右,再进行链接
		{
			if (parentparent->_left == parent)
			{
				parentparent->_left = subR;
			}
			else
			{
				parentparent->_right = subR;
			}
			subR->_parent = parentparent;
		}
		parent->_bf == subR->_bf = 0;//旋转完,平衡因子都是0
	}

右单旋

这里的右单旋就是和左单旋是一样的,只不过是方向变化了

由上图可知:在插入之前树是一颗AVL树,而插入结点之后,T的左右子树高度差的绝对值不再 <= 1,此时AVL树的平衡性被破坏,我们要对其进行旋转。

又由于是左边高,导致的平衡因子异常,所以这里进行右单旋减低高度

右单旋步骤:

  • T向右旋转成为L的右结点
  • L的右节点Y 放到 T的左孩子上

 

然后我们看看抽象图

文字解释:

  1. 让subL的右子树作为parent的左子树。
  2. 让parent作为subL的右子树。
  3. 让subL作为整个子树的根。
  4. 更新平衡因子。

一样我们不用担心会破化二叉搜索树

  1. subL的右子树当中结点的值本身就比parent的值小,因此可以作为parent的左子树。
  2. parent及其右子树当中结点的值本身就比subL的值大,因此可以作为subL的右子树。

代码理解:

void RotateR(Node* parent)
	{
		Node* subL = parent->_left;//处理旋转
		Node* subLR = subL->_right;

		subL->_right = parent;//处理关系
		parent->_left = subLR;

		Node* parentparent = parent->_parent;//保留结点
		parent->_parent = subL;

		if (subLR)//特判
			subLR->_parent = parent;

		if (parent == _root)
		{
			subL = _root;
			subL->_parent = nullptr;
		}
		else
		{
			if (parentparent->_left == parent)
			{
				parentparent->_left = subL;
			}
			else
			{
				parentparent->_right = subL;
			}
			subL->_parent = parentparent;
		}
		parent->_bf = subL->_bf = 0;
	}

右左双旋

什么时候进行右左双旋呢?

单纯的左旋解决不了问题(这里的左旋是左旋T),因为还是不平衡,所以这里需要进行右左双旋

但是注意这里的右左双旋是先右旋 R,再左旋T, 最后让L做根

第1次是右旋转:

  • R 节点 右旋转,成为L的右节点
  • L的右节点(Y2) 右旋转,成为R的左节点(即右子节点右转)

第2次是左旋转:

  • T 节点 左旋转,成为L的左节点
  • L的左节点(Y1)左旋转,成为T的右节点 (即左子节点左转)

 抽象图就是

 这是开始状态,当我们在b或者c差入的时候就引发了双旋

双旋后平衡因子改变

 如果是在c位置插入,平衡因子的改变是不一样的

 还有一种情况就是b,c是空,60这个结点就是新插入的结点

 所以这里平衡因子的更新可以根据60 这个结点的平衡因子去判断最终所以平衡因子的改变

当 60 这个结点的平衡因子为-1的时候,那么旋转完 30:0    60:0   90:1;

当 60 这个结点的平衡因子为1的时候,那么旋转完  30:-1    60:0   90:0;

当 60 这个结点的平衡因子为0的时候,那么旋转完  30:0    60:0   90:0;

所以根据上面的结论我们很容易写出代码

其中

parent:30 ;

subR:  90;

subRL:  60;

void RotateRL(Node* parent)
	{
		Node* subR = parent->_right;//先确定变量
		Node* subRL = subR->_left;
		int bf = subRL->_bf;//平衡因子,后面需要用它去判断最终的变化

		RotateR(parent->_right);//先右旋
		RotateL(parent);//再左旋

		if (bf == 0)//按照上面总结的规律去更新平衡因子
		{
			parent->_bf = subR->_bf = subRL->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			subRL->_bf = 0;
			subR->_bf = 1;
		}
		else if (bf == 1)
		{
			parent->_bf = -1;
			subRL->_bf = 0;
			subR->_bf = 0;
		}
		else
		{
			assert(false);//如果不属于上面的情况,说明出了问题,直接断言掐死
		}
	}

左右双旋

什么时候进行左右双旋呢?

单纯的右旋解决不了问题(这里的右旋是右旋T),因为还是不平衡,所以这里需要进行左右双旋

但是注意这里的左右双旋是先左旋 L,再右旋T, 最后让R做根

其实很容易发现它和右左双旋都一样,所以也分三种情况

当subLR原始平衡因子是-1时,左右双旋后parent、subL、subLR的平衡因子分别更新为1、0、0。

当subLR原始平衡因子是1时,左右双旋后parent、subL、subLR的平衡因子分别更新为0、-1、0。

当subLR原始平衡因子是0时,左右双旋后parent、subL、subLR的平衡因子分别更新为0、0、0。

所以我们也是根据平subLR的平衡因子不一样去处理的

代码理解

void RotateLR(Node* parent)
	{
		Node* subL = parent;//处理结点
		Node* subLR = subL->_right;
		int bf = subLR->_bf;//平衡因子

         //后面和右左双旋是一样的,只不过平衡因子变化有些不一样
		RotateL(parent->_left);
		RotateR(parent);
		if (bf == -1)
		{
			parent->_bf = 1;
			subLR->_bf = 0;
			subL->_bf = 0;
		}
		else if (bf == 1)
		{
			subLR->_bf = 0;
			subL->_bf = -1;
			parent->_bf = 0;
		}
		else if (bf == 0)
		{
			parent->_bf = 0;
			subL->_bf = 0;
			parent->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

四   ALV插入完整代码

#pragma once
#include<assert.h>
template<class K,class V>
struct AVLTreeNode
{
	AVLTreeNode<K, V>* _left;
	AVLTreeNode<K, V>* _right;
	AVLTreeNode<K, V>* _parent;
	pair<K, V> _kv;
	int _bf; 

	AVLTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _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;
			cur->_parent = parent;
		}
		else 
		{
			parent->_left = cur;
			cur->_parent=parent
		}
		while (parent)
		{
			if (cur == parent->_left)
			{
				parent->_bf--;
			}
			else
			{
				parent->_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)
				{
					RotateRL(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == 1)
				{
					RotateLR(parent);
				}
				break;
			}
			else
			{
				assert(false);
			}

		 }
		 
		return true;
	}
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		subR->left = parent;

		Node* parentparent = parent->_parent;
		parent->_parent = subR;
		if (subRL)
			subRL->_parent = parent;

		if (_root == parent)
		{
			subR = _root;
			subR->_parent = nullptr;
		}
		else
		{
			if (parentparent->_left == parent)
			{
				parentparent->_left = subR;
			}
			else
			{
				parentparent->_right = subR;
			}
			subR->_parent = parentparent;
		}
		parent->_bf == subR->_bf = 0;
	}

	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		subL->_right = parent;
		parent->_left = subLR;

		Node* parentparent = parent->_parent;
		parent->_parent = subL;

		if (subLR)
			subLR->_parent = parent;

		if (parent == _root)
		{
			subL = _root;
			subL->_parent = nullptr;
		}
		else
		{
			if (parentparent->_left == parent)
			{
				parentparent->_left = subL;
			}
			else
			{
				parentparent->_right = subL;
			}
			subL->_parent = parentparent;
		}
		parent->_bf = subL->_bf = 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)
		{
			parent->_bf = subR->_bf = subRL->_bf = 0;
		}
		else if (_bf == -1)
		{
			parent->_bf = 0;
			subRL->_bf = 0;
			subR->_bf = 1;
		}
		else if (_bf == 1)
		{
			parent->_bf = -1;
			subRL->_bf = 0;
			subR->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

	void RotateLR(Node* parent)
	{
		Node* subL = parent;
		Node* subLR = subL->_right;
		int bf = subLR->_bf;


		RotateL(parent->_left);
		RotateR(parent);
		if (bf == -1)
		{
			parent->_bf = 1;
			subLR->_bf = 0;
			subL->_bf = 0;
		}
		else if (bf == 1)
		{
			subLR->_bf = 0;
			subL->_bf = -1;
			parent->_bf = 0;
		}
		else if (bf == 0)
		{
			parent->_bf = 0;
			subL->_bf = 0;
			parent->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

private:
	Node* _root=nullptr;
};

五  总结

插入位置状态操作
在parent的左结点(subL)的 左子树(subL) 上做了插入元素左左型右旋
在parent的左结点(subL)的 右子树(subLR) 上做了插入元素左右型左右旋
在parent的右结点(subR)的 右子树(subR) 上做了插入元素右右型左旋
在parent的右结点(subR)的 左子树(subRL) 上做了插入元素右左型右左旋

 我们在AVL树插入元素的时候,肯定是先找的插入位置,然后插入,然后更新平衡因子,如果是子树变化导致父亲结点的平衡因子变为了 1 或者-1,那么就往上面继续更新,如果出现了2,-2则需要进行旋转,至于怎么旋转,则要看平衡因子之间的关系进行旋转(因为平衡因子体现了上面表格的具体情况),旋转完成也就是插入成功,同时也不需要再继续往上面更新了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1869699.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【包邮送书】深度学习与信号处理

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

计算机等级考试二级Java-第一篇:Java语言概述

1.java语言的历史和发展 1991年由sun公司的James Gosling负责开发的&#xff0c;一个分布式代码系统&#xff08;Oak),最初是为家用消费电子产品&#xff08;电冰箱&#xff0c;电视机等&#xff09;进行编程&#xff0c;它是java语言的前身。 1994年sun公司件目标市场转向In…

热敏晶振:成本效益的选择与温补晶振的比较

在精密电子系统的设计中&#xff0c;晶振作为时间基准源&#xff0c;其频率稳定性直接影响到整个系统的性能。其中&#xff0c;温补晶振(Temperature Compensated Crystal Oscillator&#xff0c;简称TCXO)与热敏晶振(Thermistor Compensated Crystal Oscillator)作为在特殊温度…

VS studio2019配置远程连接Ubuntu

VS studio2019配置远程连接Ubuntu 1、网络配置 &#xff08;1&#xff09;获取主机IP &#xff08;2&#xff09;获取Ubuntu的IP &#xff08;3&#xff09;在 windows 的控制台中 ping 虚拟机的 ipv4 地址&#xff0c;在 Ubuntu 中 ping 主机的 ipv4 地址。 ubuntu: ping…

centos7 安装单机MongoDB

centos7安装单机 yum 安装 1、配置yum源 vim /etc/yum.repos.d/mongodb.repo [mongodb-org-7.0] nameMongoDB Repository baseurlhttps://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/7.0/x86_64/ gpgcheck1 enabled1 gpgkeyhttps://www.mongodb.org/static/pgp…

1.3.1 离散周期信号DFS

目录 离散周期序列的DFS表示 离散周期信号DFS的性质 线性特性 位移特性 对称特性 奇偶对称 共轭反转对称 实序列的对称特性 周期卷积 DFS——Discrete Fourier Series 傅里叶级数 离散周期序列的DFS表示 做题得到的小公式 离散周期信号DFS的性质 线性特性 位…

【日志等级类编写】

日志等级类编写 这篇文章接着上篇文章&#xff0c;继续来完成日志系统。 在一个日志文件当中&#xff0c;有各种各样的等级日志 debuginfowarnerrorfatal 我们使用的时候传入的是一个等级&#xff0c;我们需要将它转换为字符串。 class LogLevel {public:enum class Level…

白敬亭章若楠甜度报表的难哄大师

#白敬亭章若楠&#xff0c;甜度爆表的难哄大师#&#x1f389;&#x1f389;&#x1f389;各位小伙伴们&#xff0c;你们还记得那个让我们心跳加速、嘴角上扬的CP组合吗&#xff1f;没错&#xff0c;就是白敬亭和章若楠&#xff01;他们可是凭借一部新剧&#xff0c;再次让我们感…

分享几个小红书获取笔记详情API接口调用实例

item_get_video-获得小红书笔记详情 smallredbook.item_get_video 公共参数 名称类型必须描述keyString是调用key&#xff08;API支持测试&#xff0c;获取测试key&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[i…

第1章 基础知识

第1章 基础知识 1.1 机器语言 机器语言就是机器指令的集合&#xff0c;机器指令展开来讲就是一台机器可以正确执行的命令 1.2 汇编语言的产生 汇编语言的主题是汇编指令。汇编指令和机器指令的差别在于指令的表示方法上&#xff0c;汇编指令是机器指令便于记忆的书写格式。…

技术干货|SimLab 电子产品热流体仿真

电子产品热仿真特点有哪些&#xff1f; 结构复杂&#xff0c;电子设备包含几十~上千个元器件 体积小&#xff0c;功率密度高、关注热敏感元器件 多种冷却方式&#xff0c;自然冷却、风扇冷却、液冷、热管等 多维度&#xff0c;芯片级&#xff0c;板级&#xff0c;系统级 单…

纯干货丨知乎广告投放流程和避坑攻略

精准有效的广告投放企业获客的关键&#xff0c;知乎作为中国最大的知识分享平台&#xff0c;拥有着高质量的用户群体和高度的用户粘性&#xff0c;为广告主提供了独一无二的品牌传播与产品推广平台。然而&#xff0c;如何在知乎上高效、精准地进行广告投放&#xff0c;避免不必…

恭喜!Z医生喜提世界名校—斯坦福大学访问学者邀请函

➡️【院校简介】 斯坦福大学&#xff08;Stanford University&#xff09;&#xff0c;全称为小利兰斯坦福大学&#xff0c;简称“斯坦福”&#xff0c;位于美国加州旧金山湾区南部帕罗奥多市境内&#xff0c;临近高科技园区硅谷&#xff0c;是私立研究型大学&#xff0c;全球…

nbcio-vue升级迁移flowable到最新的jeeg-boot-vue3的问题记录(二)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 8、用生成的代码修改api与列表字段&#xff0c;但还是显示不出来&#xff0c;api获取数据是正常的 使用BasicTable的api的时候&#xff0c;调用的api不能 // 我的发起的流程 export cons…

鸿蒙期末项目(3)

服务器搭建完成之后&#xff0c;编写了诸多api用于数据传输工作&#xff08;略&#xff09; 编写完成之后&#xff0c;回到鸿蒙开发工具&#xff0c;开始编写搜索页面的代码。 打开搜索页面时&#xff0c;先会展示历史搜索记录&#xff08;如果有的话&#xff09;&#xff0c;…

OpenAI推迟ChatGPT高级语音模式发布!谷歌将推出明星网红AI聊天机器人|AI日报

文章推荐 时序预测双飞轮&#xff0c;全面超越Transformer&#xff0c;纯MLP模型实现性能效能齐飞 OpenAI将终止对我国提供API服务&#xff0c;国内大模型将迎来“六小强”格局&#xff01;&#xff5c;AI日报 推迟ChatGPT高级语音模式发布&#xff01;OpenAI将计划在秋季向…

java注解的概念及其使用方法详细介绍

1_注解&#xff1a;概述 路径 什么是注解注解的作用 注解 什么是注解&#xff1f; 注解(Annotation)也称为元数据&#xff0c;是一种代码级别的说明注解是JDK1.5版本引入的一个特性&#xff0c;和类、接口是在同一个层次注解可以声明在包、类、字段、方法、局部变量、方法参…

WPF----进度条ProgressBar(渐变色)

ProgressBar 是一种用于指示进程或任务的进度的控件&#xff0c;通常在图形用户界面&#xff08;GUI&#xff09;中使用。它提供了一种视觉反馈&#xff0c;显示任务的完成程度&#xff0c;帮助用户了解任务的进展情况。 基本特性 Minimum 和 Maximum 属性&#xff1a; 这些属…

智能充电桩网关,构建高效充电网络

近年来我国新能源汽车的增长速度出现明显的上升趋势&#xff0c;但是其充电桩的发展还比较缓慢。目前在充电桩系统设计期间仍存在一些问题&#xff0c;主要表现在充电设施短缺、充电难等问题&#xff0c;这些问题的发生均会在一定程度上限制新能源汽车的发展&#xff0c;这就需…

华宽通中标长沙市政务共性能力建设项目,助力智慧政务建设新飞跃

在数字化浪潮的推动下&#xff0c;长沙市政府正积极拥抱智慧城市建设&#xff0c;以科技力量提升政务服务效能。华宽通凭借其卓越的技术实力与丰富的项目经验&#xff0c;成功中标长沙市政务共性能力建设项目&#xff0c;这无疑是对华宽通在智慧城市领域实力的高度认可。 华宽…