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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

星辰计划04-深入理解kafka的消息存储和索引设计

消息存储 提到存储不得不说消息的读写&#xff0c;那么kafka他是如何读写数据的呢&#xff1f; 读取消息 1.通过debug(如何debug) 我们可以得到下面的调用栈&#xff0c;最终通过FileRecords来读取保存的数据 写入消息 1.通过debug(如何debug) 我们可以得到下面的调用栈&am…

在LLMs模型中发现人类的记忆特征

论文地址&#xff1a;https://arxiv.org/abs/2311.03839 介绍 大型语言模型&#xff08;LLM&#xff09;&#xff0c;如 ChatGPT&#xff0c;为语言建模和生成人类水平的文本输出带来了质的飞跃。 这些模型在庞大的文本库中进行训练&#xff0c;有效地建立了高度复杂和准确的…

标准 I/O

标准 I/O 引言 I/O 是一切实现的基础&#xff0c;其分为标准 I/O 和文件 I/O。 文件 I/O 依赖操作系统&#xff0c;因系统的实现方式而定&#xff0c;对于程序员来说会造成很大困扰。如打开文件&#xff0c;Linux 系统调用为 open() 函数&#xff0c;而 Windows 的系统调用为…

【锁住精华】MySQL锁机制全攻略:从行锁到表锁,共享锁到排他锁,悲观锁到乐观锁

MySQL有哪些锁 1、按照锁的粒度划分 行锁 是最低粒度的的锁&#xff0c;锁住指定行的数据&#xff0c;加锁的开销较大&#xff0c;加锁较慢&#xff0c;可能会出现死锁的情况&#xff0c;锁的竞争度会较低&#xff0c;并发度相对较高。但是如果where条件里的字段没有加索引&…

OpenCV 形态学相关函数详解及用法示例

OpenCV形态学相关的运算包含腐蚀(MORPH_ERODE)&#xff0c;膨胀(MORPH_DILATE)&#xff0c;开运算(MORPH_OPEN)&#xff0c;闭运算(MORPH_CLOSE)&#xff0c;梯度运算(MORPH_GRADIENT)&#xff0c;顶帽运算(MORPH_TOPHAT)&#xff0c;黑帽运算(MORPH_BLACKHAT)&#xff0c;击中…

AI产品经理:基于大模型Agent的客服实践,更低的成本与更大的收益

现在AI客服已经在各行业普遍使用了&#xff0c;但是实际效果并不如意——用户宁愿等人工客服&#xff0c;也不愿意找AI客服解决问题。如果给当前的AI客服换成大模型&#xff0c;效果会不会更好一些&#xff1f;这篇文章&#xff0c;我们来看看作者的思考。 一、为什么要用大模型…

Python 从入门到实战30(高级文件的操作)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了操作目录的相关知识。今天我们将学习一下高级文…

一文学会 Java 8 的Predicates

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 前言 在这份详细的指南中&#xff0c;您将了解 Java Predicates&#xff0c;这是 Java 8 中一个新颖且有用的特性。本文解释了 Java Predicates 是什么以及如何在各种情况下使用它们。 在这份详尽的指南中…

游戏开发2025年最新版——八股文面试题(unity,虚幻,cocos都适用)

1.静态合批与动态合批的原理是什么&#xff1f;有什么限制条件&#xff1f;为什么&#xff1f;对CPU和GPU产生的影响分别是什么&#xff1f; 原理&#xff1a;Unity运行时可以将一些物体进行合并&#xff0c;从而用一个描绘调用来渲染他们&#xff0c;就是一个drawcall批次。 限…

信安 实验1 用Wireshark分析典型TCP/IP体系中的协议

我发现了有些人喜欢静静看博客不聊天呐&#xff0c; 但是ta会点赞。 这样的人呢帅气低调有内涵&#xff0c; 美丽大方很优雅。 说的就是你&#xff0c; 不用再怀疑哦 实验1 用Wireshark分析典型TCP/IP体系中的协议 实验目的 通过Wireshark软件分析典型网络协议数据包&a…

javaweb 实验3

我发现了有些人喜欢静静看博客不聊天呐&#xff0c; 但是ta会点赞。 这样的人呢帅气低调有内涵&#xff0c; 美丽大方很优雅。 说的就是你&#xff0c; 不用再怀疑哦 实验三 Web基础-JavaScript 目的&#xff1a; 1、 理解和掌握Javascript基本语法 2、 掌握JavaScr…

html+css+js实现Pagination 分页

效果图 HTML部分 <body><div class"pagination"><button class"prev"><</button><ul><li class"active">1</li><li>2</li><li>3</li><li>4</li><li>5…

敏捷开发与DevOps的有机结合

在当今快速变化的技术环境中&#xff0c;软件开发团队面临着前所未有的挑战。客户需求不断变化&#xff0c;市场竞争激烈&#xff0c;技术更新速度加快&#xff0c;这些因素都要求开发团队具备高度的敏捷性和高效的运营能力。为了应对这些挑战&#xff0c;越来越多的企业选择将…

024.PL-SQL进阶—游标

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

JAVA红娘婚恋相亲交友系统源码全面解析

在数字化时代&#xff0c;红娘婚恋相亲交友系统成为了连接单身男女的重要桥梁。JAVA作为一种流行的编程语言&#xff0c;为开发这样的系统提供了强大的支持。编辑h17711347205以下是对JAVA红娘婚恋相亲交友系统源码的全面解析&#xff0c;以及三段示例代码的展示。 系统概述 …

【Gitee自动化测试4】本地Git分支的增删查,本地Git分支中文件的增删查,本地文件的暂存/提交,本地分支的推送

一、流程 本地创建分支&#xff0c;设定连接什么云分支本地创建文件&#xff0c;暂存、提交–>本地分支本地分支推送所有修改–>云仓库 二、分支概念 在版本回退里&#xff0c;每次提交&#xff0c;git都把它们串成一条时间线&#xff0c;这条时间线可以理解为是一个分…

Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言&#xff0c;Verilog HDL常常需要使用语句描述并行执行的电路&#xff0c;但其实在仿真器的底层&#xff0c;这些并行执行的语句是有先后顺序…

论文阅读:LM-Cocktail: Resilient Tuning of Language Models via Model Merging

论文链接 代码链接 Abstract 预训练的语言模型不断进行微调&#xff0c;以更好地支持下游应用。然而&#xff0c;此操作可能会导致目标领域之外的通用任务的性能显著下降。为了克服这个问题&#xff0c;我们提出了LM Cocktail&#xff0c;它使微调后的模型在总体上保持弹性。…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑异步区域调频资源互济的电能、惯性与一次调频联合优化出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Spring Boot助力:小徐影院管理系统

第二章开发技术介绍 2.1相关技术 小徐影城管理系统是在Java MySQL开发环境的基础上开发的。Java是一种服务器端脚本语言&#xff0c;易于学习&#xff0c;实用且面向用户。全球超过35&#xff05;的Java驱动的互联网站点使用Java。MySQL是一个数据库管理系统&#xff0c;因为它…