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

【高阶数据结构】红黑树 {概念及性质;红黑树的结构;红黑树的实现;红黑树插入操作详细解释;红黑树的验证}

红黑树

一、红黑树的概念

红黑树(Red Black Tree) 是一种自平衡二叉查找树,在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

在这里插入图片描述

AVL树 VS 红黑树

  • 红黑树是一种特化的AVL树,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

  • AVL树要求每棵子树的左右高度差不超过1,是严格平衡;而红黑树要求最长路径不超过最短路径的2倍,是接近平衡。

  • 而红黑树是一种AVL树的变体,它要求最长路径不超过最短路径的2倍,左右子树高差有可能大于 1。所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于 AVL

  • 相对而言,插入或删除同样的数据,AVL树旋转的更多,而红黑树则旋转的更少效率相对较高


二、红黑树的性质

红黑树是每个结点都带有颜色属性的二叉查找树,颜色或红色或黑色。 在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

  • 性质1. 结点是红色或黑色。

  • 性质2. 根结点是黑色。

  • 性质3. 每个红色结点的两个子结点都是黑色。(每条路径上不能有两个连续的红色结点)

  • 性质4. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。 (每条路径上的黑色节点数量相同)

  • 性质5. 所有NIL结点都是黑色的。(NIL节点即空结点)

这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。

是性质3导致路径上不能有两个连续的红色结点确保了这个结果。最短的可能路径都是黑色结点,最长的可能路径有交替的红色和黑色结点。因为根据性质4所有路径都有相同数目的黑色结点,这就表明了没有路径能多于任何其他路径的两倍长。

思考:新插入的节点应该设为黑色还是红色?

  • 如果将新插入的节点设为黑色,不管插到那条路径都必然违反性质4。

  • 如果将新插入的节点设为红色:如果父节点是红色则违反性质3,需要进行调整;如果父节点是黑色就正常插入,无需调整。

  • 对比两种情况,最终选择将新插入的节点设为红色。


三、STL中的红黑树结构

  • 为了后续实现关联式容器map/set,STL红黑树的实现中增加一个头结点;
  • 因为根节点必须为黑色,为了与根节点进行区分,将头结点给成红色;
  • 并且让头结点的_parent域指向红黑树的根节点,_left域指向红黑树中最小的节点,_right域指向红黑树中最大的节点。

在这里插入图片描述

头结点的作用:

  • STL明确规定,begin()与end()代表的是一段前闭后开的区间,而对红黑树进行中序遍历后,可以得到一个有序的序列,因此:begin()可以放在红黑树中最小节点(即最左侧节点)的位置,end()放在最大节点(最右侧节点)的下一个位置,关键是最大节点的下一个位置在哪块?
  • 能否给成nullptr呢?答案是行不通的,因为对end()位置的迭代器进行–操作,必须要能找最后一个元素,此处就不行,因此最好的方式是将end()放在头结点的位置:

四、核心结构

enum Color{RED,BLACK
};
//红黑树的节点
template <class K, class V>
struct RBTreeNode{ RBTreeNode<K,V> *_left;RBTreeNode<K,V> *_right;RBTreeNode<K,V> *_parent;pair<K,V> _kv;Color _color; //颜色属性RBTreeNode(const pair<K,V> &kv=pair<K,V>(), Color color = RED):_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_color(color){}
};//红黑树结构
template <class K, class V>
class RBTree{ typedef RBTreeNode<K,V> Node;Node *_phead; //指向头结点的指针public:RBTree(){_phead = new Node; //红黑树的头结点_phead->_left = _phead; //起初先让头结点的左右指针指向自己_phead->_right = _phead;}Node*& GetRoot(){ //返回根节点指针的引用,便于进行修改return _phead->_parent; }//........
private:Node* LeftMost(){ //返回红黑树的最左节点指针Node *root = GetRoot();if(root == nullptr) //如果根节点为空,就返回_pheadreturn _phead;else{Node *left = root;while(left->_left!=nullptr){left = left->_left;}return left;}}Node* RightMost(){ //返回红黑树的最右节点指针Node *root = GetRoot();if(root == nullptr) //如果根节点为空,就返回_pheadreturn _phead;else{Node *right = root;while(right->_right!=nullptr){right = right->_right;}return right;}}//......
};

五、红黑树的插入操作

红黑树是在二叉搜索树的基础上加上其平衡限制条件,因此红黑树的插入可分为两步:

  1. 按照二叉搜索的树规则插入新节点

  2. 检测新节点插入后,红黑树的性质是否造到破坏。因为新节点的默认颜色是红色,因此:

    • 如果新插入的节点是根节点,需要将节点变为黑色以满足性质2。
    • 如果父节点是黑色的,没有违反红黑树的任何性质,则不需要调整;
    • 但如果父节点颜色为红色时,就违反了性质3:路径上不能有两个连续的红色结点。此时需要对红黑树分情况来讨论:

在讲解情况三、四、五之前,先说明一下:

  • cur为当前节点(关注节点),p(parent)为父节点,g(grandparent)为祖父节点,u(uncle)为叔叔节点;
  • cur不一定就是新插入的节点,也有可能是因为 cur 的子树在调整的过程中将 cur 节点的颜色由黑色改成红色。

5.1 情况一:u存在且为红

情况一: cur为红,p为红,g为黑,u存在且为红

抽象分析:

在这里插入图片描述

  1. 因为cur和p都为红色违反性质3,所以一定要把p变为黑色。
  2. 但只变p又违反性质4各路径上黑色节点的数量不同,所以要把u也变为黑色。
  3. 但原来所有路径上只有1个黑色节点(可见的)而现在变为2个。如果g树是子树,又会使整棵树违反性质4。所以要把g变为红色。
  4. g的父节点也可能是红色,所以要继续向上调整。

解决方式:变色并继续向上调整

  1. 将p,u都改为黑色,g改为红色;
  2. 如果g不为根,就把g当成cur继续向上调整;
  3. 如果g为根,就把g变为黑色。性质2:根节点是黑色的。

具体分析:

cur就是新插入的节点:

在这里插入图片描述

cur节点原来是黑色之后又被调整为红色:

在这里插入图片描述

注意:a,b,c,d,e可能是连续的几层黑色节点(要求每条路径的黑色节点数量相同),然后才出现上述情况。因为情况太多,过于复杂故作省略。


5.2 情况二:u不存在/u存在且为黑(单旋)

情况二: cur为红,p为红,g为黑,u不存在/u存在且为黑(单旋)

抽象分析:
在这里插入图片描述

  1. 因为cur和p都为红色违反性质3,所以一定要把p变为黑色。
  2. 但只变p使左路黑节点+1违反性质4,因此还要以g为轴点右单旋,使左路黑节点-1。
  3. 但此时由于右单旋使右路黑节点+1,所以要将g变为红色,右路黑节点-1。最终满足性质4。

解决方式:单旋+变色

  1. 如果p为g的左孩子,cur为p的左孩子(左左),则对g进行右单旋;
  2. 如果p为g的右孩子,cur为p的右孩子(右右),则对g进行左单旋;
  3. p、g变色–p变黑色,g变红色。
  4. 完成旋转变色后每条路径的黑节点数量相同且与插入前也相同,并且根节点为黑色不需要继续往上处理。

具体分析:u 的情况有两种

uncle节点不存在:

如果 u 节点不存在,则 cur 一定是新插入节点,因为如果 cur 不是新插入节点,则 cur 和 p 一定有一个节点的颜色是黑色,就不满足性质4:每条路径黑色节点个数相同。

在这里插入图片描述

uncle节点存在且为黑色:

如果 u 节点存在且为黑色,那么 cur 节点原来的颜色也一定是黑色的,现在看到其是红色的原因是因为 cur 的子树在调整的过程中将 cur 节点的颜色由黑色改成红色。

在这里插入图片描述

注意:a,b,c,d,e可能是连续的几层黑色节点(要求每条路径的黑色节点数量相同),然后才出现上述情况。因为情况太多,过于复杂故作省略。


5.3 情况三:u不存在/u存在且为黑(双旋)

情况三: cur为红,p为红,g为黑,u不存在/u存在且为黑(双旋)

抽象图:
在这里插入图片描述
情况三先以p为轴点左单旋,转换为情况二。

解决方式:双旋+变色

  1. p为g的左孩子,cur为p的右孩子(左右),则先对p做左单旋,再对g做右单旋;
  2. p为g的右孩子,cur为p的左孩子(右左),则先对p做右单旋,再对g做左单旋;
  3. cur、g变色–cur变黑色,g变红色。
  4. 完成旋转变色后每条路径的黑节点数量相同且与插入前也相同,并且根节点为黑色不需要继续往上处理。

具体分析:

uncle节点不存在

在这里插入图片描述

uncle节点存在且为黑色:

在这里插入图片描述

注意:a,b,c,d,e可能是连续的几层黑色节点(要求每条路径的黑色节点数量相同),然后才出现上述情况。因为情况太多,过于复杂故作省略。

总结:

  • 二叉树插入操作的难点在于通过变色和旋转操作恢复红黑树的性质,性质得到满足红黑树就能做到近似平衡:最长路径不超过最短路径的两倍。
  • 恢复的最终目的:1.关注子树满足红黑树的所有性质 2.插入前后关注子树每条路径的黑节点数量不变(保证整棵树的性质4)

5.4 插入代码

bool Insert(const pair<K,V> &kv)
{//1. 按照二叉搜索的树规则插入新节点Node* &root = GetRoot(); //这里注意要用引用接收返回值if(root == nullptr){//如果新插入的节点是根节点,需要将节点变为黑色以满足性质2root = new Node(kv, BLACK); //因为GetRoot返回指针的引用,所以改的实际是_phead->_parentroot->_parent = _phead;_phead->_left = root;_phead->_right = root;return true;}Node *cur = root;Node *parent = nullptr;while(cur != nullptr){if(kv.first > cur->_kv.first){parent = cur;cur = cur->_right;}else if(kv.first < cur->_kv.first){parent  = cur;cur = cur->_left;}else{return false;}}cur = new Node(kv,RED); //新插入的节点默认是红色的if(kv.first > parent->_kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;//2.检测新节点插入后,红黑树的性质是否造到破坏。//如果父节点是黑色的,没有违反红黑树的任何性质,则不需要调整;//但如果父节点颜色为红色时,就违反了性质3:路径上不能有两个连续的红色结点。//上一次循环中grandparent 为根节点,此次循环parent == _pheadwhile(parent != _phead && parent->_color == RED) {Node *grandparent = parent->_parent;//断言检查:grandparent一定不为空且为黑色!assert(grandparent != nullptr);assert(grandparent->_color == BLACK);Node *uncle = grandparent->_left;if(parent == grandparent->_left)uncle = grandparent->_right;if(uncle != nullptr && uncle->_color == RED) //情况一:uncle存在且为红{parent->_color = uncle->_color = BLACK; //变色grandparent->_color = RED;cur = grandparent; //继续向上调整parent = cur->_parent;}else //情况二、三:uncle不存在或uncle存在且为黑{if(parent == grandparent->_left){if(cur == parent->_left) //左左{RotateR(grandparent); //右单旋parent->_color = BLACK; //变色grandparent->_color = RED;}else{ //左右RotateL(parent); //左右双旋RotateR(grandparent);cur->_color = BLACK; //变色grandparent->_color = RED;}}else{if(cur == parent->_right) //右右{RotateL(grandparent); //左单旋parent->_color = BLACK; //变色grandparent->_color = RED;}else{ //右左RotateR(parent); //右左双旋RotateL(grandparent);cur->_color = BLACK; //变色grandparent->_color = RED;}}//旋转变色后无需继续调整,直接退出循环。break; } //end of else} //end of while//如果在调整过程中将根节点变为红色,记得重新变回黑色。if(parent == _phead) root->_color = BLACK;//令头节点的左指针指向红黑树的最左节点_phead->_left = LeftMost();//令头节点的右指针指向红黑树的最右节点_phead->_right = RightMost();return true;
}

5.5 旋转代码

void RotateL(Node *parent){Node *subR = parent->_right;Node *subRL = subR->_left;Node *ppNode = parent->_parent;parent->_right = subRL;if(subRL != nullptr){subRL->_parent = parent;}subR->_left = parent;parent->_parent = subR;if(ppNode == _phead){_phead->_parent = subR;}else{if(ppNode->_left == parent){ppNode->_left = subR;}else{ppNode->_right = subR;}}subR->_parent = ppNode;
}void RotateR(Node *parent){Node *subL = parent->_left;Node *subLR = subL->_right;Node *ppNode = parent->_parent;parent->_parent = subL;subL->_right = parent;parent->_left = subLR;if(subLR != nullptr)subLR->_parent = parent;if(ppNode == _phead){ppNode->_parent = subL;}else{if(ppNode->_left == parent){ppNode->_left = subL;}else{ppNode->_right = subL;}}subL->_parent = ppNode;
}

六、查找和遍历

Node* Find(const K &k){Node *root = GetRoot();if(root == nullptr)return nullptr;Node *cur = root;while(cur != nullptr){if(k > cur->_kv.first){cur = cur->_right;}else if(k < cur->_kv.first){cur = cur->_left;}else{return cur;}}return nullptr;
}void Inorder(){_Inorder(GetRoot());cout << endl;
}void _Inorder(Node *root){if(root == nullptr) return; _Inorder(root->_left);cout << root->_kv.first << ":" << root->_kv.second << " ";_Inorder(root->_right);
}

七、红黑树的验证

红黑树的检测分为两步:

  1. 检测其是否满足二叉搜索树(中序遍历是否为有序序列)
  2. 检测其是否满足红黑树的性质
bool IsValidRBTree(){Node *root = GetRoot();//空树也是红黑树if(root == nullptr) return true;//检查性质2:if(root->_color != BLACK){cout << "违反性质2:根节点不为黑色!" << endl;return false;}//检查性质3,4:int benchmark = 0;return _IsValidRBTree(root, 0, benchmark);
}//blacknum:用于记录当前路径的黑色节点个数,不能传引用。
//benchmark:用于记录第一条路径的黑色节点个数。需要传引用,返回给上层递归。
bool _IsValidRBTree(Node *root, int blacknum, int &benchmark){if(root == nullptr){if(benchmark == 0) //表示第一条路径遍历完{benchmark = blacknum; //记录第一条路径的黑色节点个数return true;}else{if(blacknum != benchmark) //如果其他路径的blacknum与第一条路径不同,说明违反性质4{cout << "违反性质4:从任意节点到每个叶子节点的所有路径都包含相同数目的黑色节点!" << endl;return false;}else{return true;}}}//检查性质3:if(root->_color == RED && root->_parent->_color == RED){cout << "违反性质3:路径上有两个连续的红色节点!" << endl;return false;}if(root->_color == BLACK){++blacknum; }return _IsValidRBTree(root->_left, blacknum, benchmark)&& _IsValidRBTree(root->_right, blacknum, benchmark);
}

相关文章:

【高阶数据结构】红黑树 {概念及性质;红黑树的结构;红黑树的实现;红黑树插入操作详细解释;红黑树的验证}

红黑树 一、红黑树的概念 红黑树&#xff08;Red Black Tree&#xff09; 是一种自平衡二叉查找树&#xff0c;在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有…...

获取对象占用内存

添加依赖 <dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>4.0.0</version> </dependency>添加vm启动参数 --add-opens java.base/java.langALL-UNNAMED --add-opens java.ba…...

mysql UUID 作为主键的问题

UUID 在MySQL中&#xff0c;可以使用UUID()函数来生成一个新的UUID值。该函数的返回值是一个字符串类型&#xff0c;表示一个32位的十六进制数字&#xff0c;其中包含4个连字符“-”&#xff0c;例如&#xff1a;“6ccd780c-baba-1026-9564-0040f4311e29”。 varchar(32) 32*4…...

2023高教社杯全国大学生数学建模竞赛选题建议

如下为C君的2023高教社杯全国大学生数学建模竞赛&#xff08;国赛&#xff09;选题建议&#xff0c; 提示&#xff1a;DS C君认为的难度&#xff1a;C<B<A&#xff0c;开放度&#xff1a;B<A<C 。 D、E题推荐选E题&#xff0c;后续会直接更新E论文和思路&#xf…...

分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测

分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测 目录 分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测分类效果基本介绍模型描述预测过程程序设计参考资料分类效果 基本介绍 MATLAB实现GRNN广义回归神经网络多特...

低功耗窗帘电机解决方案成功应用并通过 Matter 1.1 认证

Nordic Semiconductor官方宣布与HooRii Tech&#xff08;和众科技&#xff09;携手合作&#xff0c;基于 Nordic nRF52840 芯片平台打造的 HRN71模组&#xff0c;成功赋能低功耗窗帘电机品牌发布Matter产品。低功耗窗帘电机获得 Matter 1.1 认证意味着它具有与其他 Matter 认证…...

如何修复老照片?老照片修复翻新的方法

老旧照片&#xff0c;尤其是黑白照片&#xff0c;往往因为年代久远、保存方式不当等原因而出现褪色、污损、划痕等问题&#xff0c;会比较难以修复&#xff0c;就算是技术精湛的专业修复师&#xff0c;也是需要投入极大时间精力的&#xff0c;效果也是不可预料的。 修复老照片…...

MySQL:区分大小写

查看MySQL版本 show variables; 1、查看 MySQL 当前的区分大小写设置&#xff1a; SHOW VARIABLES LIKE lower_case_table_names; 或者 show Variables like %table_names 2、更改大小写敏感设置&#xff1a; 在 MySQL 5.7 中&#xff0c;更改大小写敏感设置要求修改配置文件 …...

刷题笔记19——优势洗牌和去重保持字典序

摆出无比亲密的态度&#xff0c;装模作样地与对方套近乎&#xff0c;频繁地联系对方。这都说明他们并不相信自己得到了对方的信赖&#xff0c;若是互相信赖&#xff0c;便不会依赖亲密的感觉。在外人看来&#xff0c;反而显得冷淡。 ——尼采《人性的&#xff0c;太人性的》 ha…...

星际争霸之小霸王之小蜜蜂(十一)--杀杀杀

系列文章目录 星际争霸之小霸王之小蜜蜂&#xff08;十&#xff09;--鼠道 星际争霸之小霸王之小蜜蜂&#xff08;九&#xff09;--狂鼠之灾 星际争霸之小霸王之小蜜蜂&#xff08;八&#xff09;--蓝皮鼠和大脸猫 星际争霸之小霸王之小蜜蜂&#xff08;七&#xff09;--消失…...

腾讯云免费SSL证书申请流程_每年免费50个HTTPS证书

2023腾讯云免费SSL证书申请流程&#xff0c;一个腾讯云账号可以申请50张免费SSL证书&#xff0c;免费SSL证书为DV证书&#xff0c;仅支持单一域名&#xff0c;申请腾讯云免费SSL证书3分钟即可申请成功&#xff0c;免费SSL证书品牌为TrustAsia亚洲诚信&#xff0c;腾讯云百科分享…...

C#上位机开发目录

C#上位机序列1: 多线程&#xff08;线程同步&#xff0c;事件触发&#xff0c;信号量&#xff0c;互斥锁&#xff0c;共享内存&#xff0c;消息队列&#xff09; C#上位机序列2: 同步异步(async、await) C#上位机序列3: 流程控制&#xff08;串行&#xff0c;并行&#xff0c…...

网络通信基础

IP地址 使用ip地址来描述网络上一个设备所在的位置 端口号 区分一个主机上不同的程序,一个网络程序,在启动的时候,都需要绑定一个或者多个端口号,后续的通信过程都需要依赖端口号来进行展开的,mysql默认的端口号是3306 协议 描述了网络通信传输的数据的含义,表示一种约定,…...

框架分析(10)-SQLAlchemy

框架分析&#xff08;10&#xff09;-SQLAlchemy 专栏介绍SQLAlchemy特性分析ORM支持数据库适配器事务支持查询构建器数据库连接池事务管理器数据库迁移特性总结 优缺点优点强大的对象关系映射支持多种数据库灵活的查询语言自动管理数据库连接支持事务管理易于扩展和定制 缺点学…...

Linux/Windows中根据端口号关闭进程及关闭Java进程

目录 Linux 根据端口号关闭进程 关闭Java服务进程 Windows 根据端口号关闭进程 Linux 根据端口号关闭进程 第一步&#xff1a;根据端口号查询进程PID&#xff0c;可使用如下命令 netstat -anp | grep 8088&#xff08;以8088端口号为例&#xff09; 第二步&#xff1a;…...

基于springboot实现了后台定时统计数据报表并将数据生成excel文件作为附件,然后通过邮件发送通知的功能

概述 本例子基于springboot实现了后台定时统计数据报表并将数据生成excel文件作为附件&#xff0c;然后通过邮件发送通知的功能。 详细 一、准备工作 1、首先注册两个邮箱&#xff0c;一个发送邮箱&#xff0c;一个接收邮箱。 2、发送邮箱开启IMAP/SMTP/POP3服务&#xff0c…...

opencv 提取选中区域内指定hsv颜色的水印

基于《QT 插件化图像算法研究平台》做的功能插件。提取选中区域内指定hsv颜色的水印。 《QT 插件化图像算法研究平台》有个HSV COLOR PICK功能&#xff0c;可以很直观、方便地分析出水印 的hsv颜色&#xff0c;比如, 蓝色&#xff1a;100,180,0,255,100,255。 然后利用 opencv …...

如何理解张量、张量索引、切片、张量维度变换

Tensor 张量 Tensor&#xff0c;中文翻译“张量”&#xff0c;是一种特殊的数据结构&#xff0c;与数组和矩阵非常相似。在 PyTorch 中&#xff0c;使用张量对模型的输入和输出以及模型的参数进行编码。 Tensor 是一个 Python Class。PyTorch 官方文档中定义“Tensor&#xff0…...

基于SpringBoot的汽车租赁系统

基于SpringBootVue的汽车租赁系统&#xff0c;前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 角色&#xff1a;管理员、业务员、用户 管理员 用户管理…...

怎么做手机App测试?app测试详细流程和方法介绍

APP测试 1、手机APP测试怎么做&#xff1f; 手机APP测试&#xff0c;主要针对的是android和ios两大主流操作系统&#xff0c;主要考虑的就是功能性、兼容性、稳定性、易用性&#xff08;也就是人机交互&#xff09;、性能。 手机APP测试前的准备&#xff1a; 1.使用同类型的…...

【计算机网络】网络编程接口 Socket API 解读(1)

Socket 是网络协议栈暴露给编程人员的 API&#xff0c;相比复杂的计算机网络协议&#xff0c;API 对关键操作和配置数据进行了抽象&#xff0c;简化了程序编程。 本文讲述的 socket 内容源自 Linux 发行版 centos 9 上的 man 工具&#xff0c;和其他平台&#xff08;比如 os-x …...

IGES在线查看与转换

IGES 格式最初由美国空军开发并于 1980 年发布。该格式是集成计算机辅助制造 (ICAM) 项目的产品,该项目旨在通过集成操作来降低制造成本。 IGES 文件旨在允许航空航天相关设计在不同平台上传输,同时将数据丢失降至最低。 在 IGES 格式出现之前,不同公司创建的 CAD 和计算机…...

【Vue3-Vite】Vite配置--路径别名配置

路径别名配置 使用 代替 src Vite配置 // vite.config.ts import {defineConfig} from vite import vue from vitejs/plugin-vueimport path from pathexport default defineConfig({plugins: [vue()],resolve: {alias: {"": path.resolve("./src") // …...

道可云元宇宙每日资讯|第二届世界元宇宙大会将在嘉定安亭举行

道可云元宇宙每日简报&#xff08;2023年9月6日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 第二届世界元宇宙大会将于9月20日在嘉定安亭举行 元起嘉定&#xff0c;虚实相生&#xff0c;产业赋能。由中国仿真学会、中国指挥与控制学会和北京理工大学共同主办&a…...

Python for 循环语句

Python for循环可以遍历任何序列的项目&#xff0c;如一个列表或者一个字符串。 语法&#xff1a; for循环的语法格式如下&#xff1a; for iterating_var in sequence:statements(s) 流程图&#xff1a; ​ 实例 #!/usr/bin/python # -*- coding: UTF-8 -*- for letter in …...

iOS脱壳之frida-ios-dump

frida-ios-dump介绍 该工具基于frida提供的强大功能通过注入js实现内存dump然后通过python自动拷贝到电脑生成ipa文件&#xff0c;适合现iOS11版本之后的越狱手机使用。 下载 https://github.com/AloneMonkey/frida-ios-dump环境安装 电脑环境安装 win和Mac 环境一样都是…...

rust中的reborrow和NLL

reborrow 我们看下面这段代码 fn main() {let mut num 123;let ref1 &mut num; // 可变引用add(ref1); // 传递给 add 函数println!("{}", ref1); // 再次使用ref1 }fn add(num: &mut i32) {println!("{}", *num); }我们…...

Java设计模式:一、六大设计原则-04:迪米特法则

文章目录 一、定义&#xff1a;迪米特法则二、模拟场景&#xff1a;迪米特法则原则三、违背方案&#xff1a;迪米特法则原则3.1 工程结构3.2 学生、老师、校长类3.2.1 学生类3.2.2 老师类3.2.3 校长类 3.3 单元测试 四、改善代码&#xff1a;迪米特法则原则4.1 工程结构4.2 学生…...

使用docker部署pg数据库

使用 Docker 部署 PostgreSQL 数据库是一种常见的做法&#xff0c;它提供了方便、可移植和可重复的方式来运行数据库。下面是一个简单的示例&#xff0c;用于在 Docker 中部署 PostgreSQL 数据库&#xff1a; 首先&#xff0c;确保您已经安装了 Docker 并正确配置了 Docker 环境…...

Json“牵手”亚马逊商品详情数据方法,亚马逊商品详情API接口,亚马逊API申请指南

亚马逊平台是美国最大的一家网络电子商务公司&#xff0c;亚马逊公司是1995年成立&#xff0c;刚开始只做网上书籍售卖业务&#xff0c;后来扩展到了其他产品。现在已经是全世界商品品种最多的网上零售商和第二互联网公司&#xff0c;亚马逊是北美洲、欧洲等地区的主流购物平台…...

装修设计费一般多少钱一平方/南昌seo计费管理

原文地址&#xff1a;http://hi.baidu.com/baowup/blog/item/3a27465c86d71546faf2c066.html/cmtid/de1ef3f0de7554a0a40f52f7 string类的构造函数&#xff1a; string(const char *s); //用c字符串s初始化 string(int n,char c); //用n个字符c初始化 此外&#xff0c;s…...

黑马程序员上海校区/baike seotl

文章目录测试环境multiset介绍头文件模块类定义对象构造初始化元素访问元素插入和删除元素查找容器大小迭代器其他函数测试环境 系统&#xff1a;ubuntu 22.04.2 LTS 64位 gcc版本&#xff1a;11.3.0 编辑器&#xff1a;vsCode 1.76.2 multiset介绍 关联式容器。元素是唯一的…...

网站编辑的职业特点有哪些/百度文库官网入口

1、顺序结构 顺序结构的程序设计是最简单的&#xff0c;只要按照解决问题的顺序写出相应的语句就行&#xff0c;它的执行顺序是自上而下&#xff0c;依次执行。 例如&#xff1b;a 3&#xff0c;b 5&#xff0c;现交换a&#xff0c;b的值&#xff0c;这个问题就好像交换两个…...

有哪些可以接单做任务的网站/深圳网站提升排名

前言 有的时候&#xff0c;配置信息是我们无法在开发过程中就能确定的。比如&#xff0c;给客户开发的项目&#xff0c;客户需要根据自身的情况自定义配置&#xff0c;如数据库配置&#xff0c;加密密钥配置等等。这时候&#xff0c;就需要把配置文件放在外面&#xff0c;让用户…...

合肥餐饮网站建设/关于进一步优化 广州

为什么80%的码农都做不了架构师&#xff1f;>>> 1. 背景 在做性能测试的时候&#xff0c;很多人都用并发用户数来衡量系统的性能&#xff0c;觉得系统能支撑的并发用户数越多&#xff0c;系统的性能就越好&#xff1b;对TPS不是非常理解&#xff0c;也根本不知道它…...

域名备案要先做网站的吗/企业建站都有什么网站

我对python了解不多&#xff0c;但似乎可以接收JSON格式的数据(参见Python - Parsing JSON Data Set)SAS提供了一个免费的工具&#xff0c;可以轻松地以JSON格式发送数据集(它是为与javascript通信而构建的&#xff0c;但在您的情况下应该也能很好地工作)。.sas文件可以在这里下…...