详解 【AVL树】

AVL树实现

  • 1. AVL的概念
  • AVL树的实现
    • 2.1 AVL树的结点结构
    • 2.2 AVL树的插入
      • 2.2.1 AVL树的插入的一个大概操作:
      • 2.2.2 AVL树的平衡因子更新
      • 2.2.3 平衡因子的停止条件
      • 2.2.4 再不考虑旋转的角度上实现AVL树的插入
    • 2.3 旋转
      • 2.3.1 旋转的原则
      • 2.3.2 右单旋
      • 2.2.3 右单旋代码实现
      • 2.3.4 左单旋
      • 2.3.5 左单旋代码实现
      • 2.3.6 左右双旋
      • 2.3.7 左右双旋代码实现
    • 2.4 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树实现这⾥我们引⼊⼀个平衡因⼦(balance factor)的概念,每个结点都有⼀个平衡因⼦,任何
结点的平衡因⼦等于右⼦树的⾼度减去左⼦树的⾼度,也就是说任何结点的平衡因⼦等于0/1/-1,
AVL树并不是必须要平衡因⼦,但是有了平衡因⼦可以更⽅便我们去进⾏观察和控制树是否平衡,
就像⼀个⻛向标⼀样。

• 思考⼀下为什么AVL树是⾼度平衡搜索⼆叉树,要求⾼度差不超过1,⽽不是⾼度差是0呢?0不是更
好的平衡吗?画画图分析我们发现,不是不想这样设计,⽽是有些情况是做不到⾼度差是0的。⽐
如⼀棵树是2个结点,4个结点等情况下,⾼度差最好就是1,⽆法作为⾼度差是0

• AVL树整体结点数量和分布和完全⼆叉树类似,⾼度可以控制在logN ,那么增删查改的效率也可
以控制在 O(logN),相⽐⼆叉搜索树有了本质的提升

列如:
当树的平衡因子达到2时就要旋转:
在这里插入图片描述
插入到14的左节点,使得10的平衡因子变成2。
在这里插入图片描述
因为AVL树的左右高度相差不超过2,那么我们就要旋转来改变树的结构

AVL树的实现

2.1 AVL树的结点结构

                                                  结点的结构
template<class K,class V>
struct AVLTreeNode
{
public:
pair<K,L> _kv;
AVLTreeNode<K,V>* _left;
AVLTreeNode<K,V>* _right;
AVLTreeNode<K,V>* _parent;
int _bf=0;平衡因子
AVLTreeNode(const pair<K,V>& kv)
 :_kv(kv)
 ,_left(nullptr)
 ,_rigth(nullptr)
 ,_parent(nullptr)
 ,_bf(0)
{}
};

结点需要以下几个元素组成:

1:数据(Key,Value)pair类型的数据

2:节点指针(为方便指向结点,进行更新)

3:平衡因子(时刻保持着树的高度之差<2)

2.2 AVL树的插入

2.2.1 AVL树的插入的一个大概操作:

1、插入时,如果树结点为空,那么就直接构造节点,直接插入
2、插入时要按照搜索二叉树规则来进行插入
3、插入后,平衡因子只会影响租先结点的高度,也就是说祖先结点的平衡因子会改变,
那么平衡因子更新规律(从新增结点开始,往上传(这就体现了父亲节点指针的用处了),直到特殊条件停止或更新到根结点了)
特殊条件下面会讲~
4、更新平衡因⼦过程中没有出现问题,则插⼊结束
5、如果更新时出现平衡因子为二的情况时就要旋转了

2.2.2 AVL树的平衡因子更新

更新规则:
1:
平衡因子=右高度-左高度 ------------------------ (同时也可以 平衡因子= 左高度-右高度,那么以下更新平衡因子的规则就要改变)
2:
只有当前结点的高度改变时,才会导致结点的平衡因子改变
在这里插入图片描述
当插入13时高度改变,使得10的平衡因子的改变

在这里插入图片描述
3:
插⼊结点,会增加⾼度,所以新增结点在parent的右⼦树,parent的平衡因⼦++,新增结点在parent的左⼦树,parent平衡因子

4:
parent所在⼦树的⾼度是否变化决定了是否会继续往上更新

2.2.3 平衡因子的停止条件

1:
更新后parent的平衡因⼦等于0,更新中parent的平衡因⼦变化为-1->0 或者 1->0,说明更新前
parent⼦树⼀边⾼⼀边低,新增的结点插⼊在低的那边,插⼊后parent所在的⼦树⾼度不变,不会
影响parent的⽗亲结点的平衡因⼦,更新结束。

如图:
变化前:
在这里插入图片描述

变化后:
在这里插入图片描述
2:
更新后parent的平衡因⼦等于1 或 -1,更新前更新中parent的平衡因⼦变化为0->1 或者 0->-1,说
明更新前parent⼦树两边⼀样⾼,新增的插⼊结点后,parent所在的⼦树⼀边⾼⼀边低,parent所
在的⼦树符合平衡要求,但是⾼度增加了1,会影响arent的⽗亲结点的平衡因⼦,所以要继续向上更新。

在这里插入图片描述

3:
更新后parent的平衡因⼦等于2 或 -2,更新前更新中parent的平衡因⼦变化为1->2 或者 -1->-2,说
明更新前parent⼦树⼀边⾼⼀边低,新增的插⼊结点在⾼的那边,parent所在的⼦树⾼的那边更⾼
了,破坏了平衡,parent所在的⼦树不符合平衡要求,需要旋转处理,旋转的⽬标有两个:1、把
parent⼦树旋转平衡。2、降低parent⼦树的⾼度,恢复到插⼊结点以前的⾼度。所以旋转后也不
需要继续往上更新,插⼊结束。

(1)
往高的那边你插入数据导致平衡因子变为2
在这里插入图片描述

2.2.4 再不考虑旋转的角度上实现AVL树的插入

typedef AVLTreeNode<K,V> Node;
bool insert(const pair<K,V>& kv)
{
1:根节点为空则直接构造赋值
if(_root=nullptr)
{
 _root=new Node(kv);
 return true;插入完成给值
}
找出kv的位置
Node* parent=nullptr
Node* cur=_root;
while(cur)
{
if(cur->_kv.first<kv.first)
{
 插入的值大于cur指向结点的值,那么久往右找
 parent=cur;
 cur=cur->_right;
}
else if(cur->_kv.first>kv.first)
{
  插入的值小于当前节点的值,那么就往左走
  parent=cur;
  cur=cur->_left;
}
else
{
  找到与kv.first 的结点的值,那么久返回插入失败
  return false
}
}
出来这个循环后,就要构建结点来连接了
cur=new Node(kv);
if(parent->_kv.first<kv.first)这里用父亲节点来连接
{
 parent->_right=cur;
}
else
{
parent->_left=cur;
}
cur->_parent=parent;别忘了是三叉链(这里博主就会经常忘记)


插入节点后,开始调节平衡因子:
while(parent)因为从parent插入结点,那么避免不了要改变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)
{
这里就需要旋转,因为现在不考虑旋转,所以这里空着
break;
}
else
{
其他因素
assert(false);用assert报错
}
}
}
return true; 走到这里返回成功
}

2.3 旋转

2.3.1 旋转的原则

1. 保持搜索树的规则
2. 让旋转的树从不满⾜变平衡,其次降低旋转树的⾼度
旋转总共分为四种,左单旋/右单旋/左右双旋/右左双旋。
说明:下⾯的图中,有些结点我们给的是具体值,如10和5等结点,这⾥是为了⽅便讲解,实际中是什
么值都可以,只要⼤⼩关系符合搜索树的规则即可。

2.3.2 右单旋

• 本图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整棵树的⼀个局部⼦树,旋转后不会再影响上⼀层,插⼊结束了。

在这里插入图片描述

也就是说旋转是哪边高就往那边压数据:
1、这里的左节点太高了那么就把结点5往右压10
2、5作为根结点,5的右边结点给了10的左边结点
3、10变成了5的右边结点

按照以上规律:
既能保持旋转后还是AVL树,还能让平衡因子更新成<2

根据不同情况结果也不一样:
a、b、c
h=0

在这里插入图片描述

h=1
在这里插入图片描述

h=2
在这里插入图片描述
这里a的结构只能是x,因为为y或z时那么旋转的结点就不是5了,而是y或z结点*
那么a就只有4处可以插入值导致5的平衡因子为2,而b或c是以上x,y,z三种情况都可以
那么搭配就有3**3*4=36种搭配结果

2.2.3 右单旋代码实现

void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
// 需要注意除了要修改孩⼦指针指向,还是修改⽗亲
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
Node* parentParent = parent->_parent;
subL->_right = parent;
parent->_parent = subL;
// parent有可能是整棵树的根,也可能是局部的⼦树
// 如果是整棵树的根,要修改_root
// 如果是局部的指针要跟上⼀层链接
if (parentParent == nullptr)
{
_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;
}

2.3.4 左单旋

• 本图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整棵树的⼀个局部⼦树,旋转后不会再影响上⼀层,插⼊结束了。

在这里插入图片描述
这里与右单旋大差不差

2.3.5 左单旋代码实现

void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if(subRL)
subRL->_parent = parent;
Node* parentParent = parent->_parent;
subR->_left = parent;
parent->_parent = subR;
if (parentParent == nullptr)
{
_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;
}

2.3.6 左右双旋

通过图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。

在这里插入图片描述

这里可以看出来8左旋后把左节点连接到5的右结点上来。
再来一个右旋使得8为根了,而8的右结点给了10的左节点了

如果是:左边结点高,且不是插入到a的子树上的,先左旋在右旋
------------右边结点高,且不是插入到a的子树上的,那么就先右旋在左旋

2.3.7 左右双旋代码实现

void RotateLR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
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;
parent->_bf = 1;
}
else if(bf == 1)
{
subL->_bf = -1;
subLR->_bf = 0;
parent->_bf = 0;
}
else
{
assert(false);
}
}

2.4 AVL树平衡检测

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

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;
}
// pRoot的左和右如果都是AVL树,则该树—定是AVL树
return _IsBalanceTree(root->_left) && _IsBalanceTree(root->_right);
}
// 测试代码
void TestAVLTree1()
{
AVLTree<int, int> t;
// 常规的测试⽤例
//int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
// 特殊的带有双旋场景的测试⽤例
int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
for (auto e : a)
{
t.Insert({ e, e });
}
t.InOrder();
cout << t.IsBalanceTree() << endl;
}
// 插⼊—堆随机值,测试平衡,顺便测试—下⾼度和性能等
void TestAVLTree2()
{
const int N = 100000;
vector<int> v;
v.reserve(N);
srand(time(0));
for (size_t i = 0; i < N; i++)
{
v.push_back(rand()+i);
}
size_t begin2 = clock();
AVLTree<int, int> t;
for (auto e : v)
{
t.Insert(make_pair(e, e));
}
size_t end2 = clock();
cout << "Insert:" << end2 - begin2 << endl;
cout << t.IsBalanceTree() << endl;
cout << "Height:" << t.Height() << endl;
cout << "Size:" << t.Size() << endl;
size_t begin1 = clock();
// 确定在的值
/*for (auto e : v)
{
t.Find(e);
}*/
// 随机值
for (size_t i = 0; i < N; i++)
{
t.Find((rand() + i));
}
size_t end1 = clock();
cout << "Find:" << end1 - begin1 << endl;

结束!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 爬虫从入门到(不)入狱学习笔记

爬虫的流程&#xff1a;从入门到入狱 1 获取网页内容1.1 发送 HTTP 请求1.2 Python 的 Requests 库1.2 实战&#xff1a;豆瓣电影 scrape_douban.py 2 解析网页内容2.1 HTML 网页结构2.2 Python 的 Beautiful Soup 库 3 存储或分析数据&#xff08;略&#xff09; 一般爬虫的基…

一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测

一区北方苍鹰算法优化创新改进Transformer&#xff01;NGO-Transformer-LSTM多变量回归预测 目录 一区北方苍鹰算法优化创新改进Transformer&#xff01;NGO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab NGO-Transformer-LST…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二十集:制作专门渲染HUD的相机HUD Camera和画布HUD Canvas

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作HUD Camera以及让两个相机同时渲染屏幕二、制作HUD Canvas 1.制作法力条Soul Orb引入库2.制作生命条Health读入数据3.制作吉欧统计数Geo Counter4.制作…

Opencv+ROS自编相机驱动

目录 一、工具 二、原理 代码 标定 三、总结 参考&#xff1a; 一、工具 opencv2ros ubuntu18.04 usb摄像头 二、原理 这里模仿usb_cam功能包对Opencv_ros进行修饰&#xff0c;加上相机参数和相机状态&#xff0c;难点在于相机参数的读取。 对于相机参数话题 camera…

计算机网络 | 7.网络安全

1.网络安全问题概述 &#xff08;1&#xff09;计算机网络面临的安全性威胁 <1>计算机网络面临的完全性威胁 计算机网络面临的两大类安全威胁&#xff1a;被动攻击和主动攻击 被动攻击 截获&#xff1a;从网络上窃听他人的通信内容。主动攻击 篡改&#xff1a;故意篡改…

机器翻译基础与模型 之四:模型训练

1、开放词表 1.1 大词表和未登陆词问题 理想情况下&#xff0c;机器翻译应该是一个开放词表&#xff08;Open Vocabulary&#xff09;的翻译任务。也就是&#xff0c;无论测试数据中包含什么样的词&#xff0c;机器翻译系统都应该能够正常翻译。 现实的情况是即使不断扩充词…

ThingsBoard规则链节点:Azure IoT Hub 节点详解

目录 引言 1. Azure IoT Hub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 设备管理 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c;提供了设备…

MongoDB相关问题

视频教程 【GeekHour】20分钟掌握MongoDB Complete MongoDB Tutorial by Net Ninja MongoDB开机后调用缓慢的原因及解决方法 问题分析&#xff1a; MongoDB开机后调用缓慢&#xff0c;通常是由于以下原因导致&#xff1a; 索引重建&#xff1a; MongoDB在启动时会重建索引…

三种蓝牙架构实现方案

一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块&#xff0c;每颗SoC或者模块都有自己独有的功能&#xff0c;比如手机应用跑在AP芯片上&#xff0c;显示屏&#xff0c;3G/4G通信&#xff0c;WiFi/蓝牙等都有自己专门的SoC或者模块&#xff0…

sql工具!好用!爱用!

SQLynx的界面设计简洁明了&#xff0c;操作逻辑清晰易懂&#xff0c;没有复杂的图标和按钮&#xff0c;想对哪部分操作就在哪里点击右键&#xff0c;即使你是数据库小白也能轻松上手。 尽管SQLynx是一款免费的工具&#xff0c;但是它的功能却丝毫不逊色于其他付费产品&#xff…

UE5肉鸽游戏教程学习

学习地址推荐&#xff1a;UE5肉鸽项目实战教程_哔哩哔哩_bilibili

反向代理服务器的用途

代理服务器在网络中扮演着重要的角色&#xff0c;它们可以优化流量、保护服务器以及提高安全性。在代理服务器中&#xff0c;反向代理服务器是一种特殊类型&#xff0c;常用于Web服务器前&#xff0c;它具备多种功能&#xff0c;能够确保网络流量的顺畅传输。那么&#xff0c;让…

面试经典 150 题:205,55

205. 同构字符串 【解题思路】 来自大佬Krahets 【参考代码】 class Solution { public:bool isIsomorphic(string s, string t) {map<char, char> Smap, Tmap;for(int i0; i<s.size(); i){char a s[i], b t[i];//map容器存在该字符&#xff0c;且不等于之前映射…

信创改造 - TongRDS 替换 Redis

记得开放 6379 端口哦 1&#xff09;首先在服务器上安装好 TongRDS 2&#xff09;替换 redis 的 host&#xff0c;post&#xff0c;passwd 3&#xff09;TongRDS 兼容 jedis # 例如&#xff1a;更改原先 redis 中对应的 host&#xff0c;post&#xff0c;passwd 改成 TongRDS…

嵌入式工程师面试笔试总结——day1

第一章、进程与线程 1、什么是进程、线程&#xff0c;有什么区别&#xff1f; 进程是资源&#xff08; CPU 、内存等&#xff09;分配的基本单位&#xff0c;线程是 CPU 调度和分配的基本单位&#xff08;程序执行的最小单 位&#xff09;。同一时间&#xff0c;如果CPU 是单…

算法之区间和题目讲解

题干 难度&#xff1a;简单 题目分析 题目要求算出每个指定区间内元素的总和。 然而&#xff0c;区间在输入的最下面&#xff0c;所以按照暴力破解的思路&#xff0c;我们首先要遍历数组&#xff0c;把它的值都存进去。 然后&#xff0c;遍历下面的区间&#xff0c;从索引a…

泷羽sec-linux

基础之linux 声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团…

用 Python 从零开始创建神经网络(十):优化器(Optimizers)(持续更新中...)

优化器&#xff08;Optimizers&#xff09; 引言1. 随机梯度下降/Stochastic Gradient Descent (SGD)2. 学习率&#xff08;Learning Rate&#xff09;3. 学习率衰减&#xff08;Learning Rate Decay&#xff09;4. 带动量的随机梯度下降法&#xff08;Stochastic Gradient Des…

UE5安装教程及设置

学习链接&#xff1a;01-安装UE5及设置_哔哩哔哩_bilibili

如何利用Python爬虫精准获得1688店铺的所有商品信息

在数字化时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是在电商领域。1688作为中国领先的B2B电商平台&#xff0c;拥有丰富的商品数据。对于电商企业来说&#xff0c;获取这些数据对于市场分析、竞品研究等具有重要意义。本文将详细介绍如何使用Python编写爬虫程序&…