实现红黑树

news2024/11/27 0:22:43

目录

红黑树的概念

红黑树的节点结构定义

红黑树的插入

红黑树的验证

实现红黑树完整代码


红黑树的概念

红黑树 ,是一种 二叉搜索树 ,但 在每个结点上增加一个存储位表示结点的颜色,可以是 Red
Black 。 通过对 任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路
径会比其他路径长出俩倍 ,因而是 接近平衡 的。
注意:可以认为AVL树是严格平衡的,而红黑树是近似平衡的
而上述所说的 对任何一条从根到叶子的路径上各个结点着色方式的限制具体如下:
1. 每个结点不是红色就是黑色
2. 根节点是黑色的 
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(不存在连续的红色节点)
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点 
5. 每个叶子结点都是黑色的 ( 此处的叶子结点指的是空结点 )

有了上述限制,最短路径就是只包含黑色节点的路径,而最长路径就是黑红交替,所以所有路径长度范围都在[最短路径,最短路径的2倍]这个区间之间, 保证了红黑树近似平衡

红黑树的节点结构定义

//颜色定义成枚举类型
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 _col;

	RBTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _col(RED)
	{}
};

红黑树的插入

插入新节点我们选择插入红色节点,理由如下:

1.插入黑色节点,一定破坏性质4,所有路径的黑色节点个数都要变化

2.插入红色节点,可能破坏性质3,插入红色节点的父亲是黑色节点,没有破坏性质3, 不需要调整;插入红色节点的父亲是红色节点,破坏了性质3, 需要进行调整

综合考虑,插入红色节点的代价相比插入黑色节点小很多,因此我们选择插入红色节点

插入情况的分类:

上面已经提到,插入红色节点的父亲是黑色节点,没有破坏性质3,因此无需调整,因此下面只讨论插入红色节点的父亲是红色节点的情况

处理方法总体分两类

1.插入节点的叔叔节点存在且为红色 --- 变色即可

字母含义: cur --- 插入节点, p --- cur的父亲节点,  g --- cur的爷爷节点, u --- cur的叔叔节点

ps: g一定存在,因为p是红色节点, 不可能为根节点, 而g也一定是黑色节点,因为如果是红色节点,说明在cur插入之前红黑树就已经出问题了!

插入之后cur和p都是红色,因为不能出现连续红色节点,我们选择把p变黑,而p变黑之后,g-p-cur的这条路径多了一个黑色节点,因此我们又把g变红,g变红之后,g-u的这条路径又少了一个黑色节点,由于叔叔节点存在且为红色,因此我们又把u变黑即可

ps:变色完之后,发现g变成了红色,而上图的树可能只是一颗子树,因此g变红之后,接着:

1.如果g是根,把g变黑,因为红黑树要求根节点是黑色

2.如果g不是根,g必然有父亲,继续判断g的父亲节点的颜色,如果g的父节点是黑色,停止处理(因为没有再违反红黑树规则了);如果g的父节点是红色,此时又出现了连续的红节点,需要继续处理, 把cur更新到g的位置,继续循环处理!

2.插入节点的叔叔节不存在 或者 存在且为黑色 --- 旋转 + 变色

这种情况下,单纯的变色已经解决不了问题了!需要 旋转+变色 来处理

具体采用哪种旋转方法,在前面的博客 实现AVL树-CSDN博客 已经讲解过了

注意:无论是哪种旋转+变色方式,发现最终当前子树的根节点都变成了黑色,此时无论cur的父节点是黑色还是红色都不违反红黑树的规则,因此旋转+变色完成之后,直接break跳出循环即可!

右单旋 + 变色 (p是g的左,cur是p的左)

左右双旋 + 变色 (p是g的左,cur是p的右)

 左单旋 + 变色 (p是g的右,cur是p的右)

右左双旋 + 变色 (p是g的右,cur是p的左)

红黑树旋转代码(除了不需要调平衡因子,其他代码与AVL树一样):

	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 (parentParent == nullptr)
		{
			_root = subR;
			_root->_parent = nullptr;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}

			subR->_parent = parentParent;
		}
	}

	//右单旋
	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;

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

			subL->_parent = parentParent;
		}
	}

	//左右双旋
	void RotateLR(Node* parent)
	{
		RotateL(parent->_left);
		RotateR(parent);
	}

	//右左双旋
	void RotateRL(Node* parent)
	{
		RotateR(parent->_right);
		RotateL(parent);
	}

红黑树插入代码:

bool Insert(const pair<K, V>& kv)
{
	if (_root == nullptr)
	{
		_root = new Node(kv);
		_root->_col = BLACK;
		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 && parent->_col == RED) //父亲不存在或者父亲为黑色就不需要继续调整了!
	{
		Node* grandfather = parent->_parent;
		if (grandfather->_left == parent) //父亲是爷爷的左孩子
		{
			Node* uncle = grandfather->_right;
			//1.插入节点的叔叔存在且为红色 --- 父亲和叔叔变黑,爷爷变红
			if (uncle && uncle->_col == RED)
			{
				parent->_col = uncle->_col = BLACK;
				grandfather->_col = RED;

				//调整完之后,更新cur, 判断是否还需要调整
				cur = grandfather;
				parent = cur->_parent;
			}
			//2.uncle不存在 / uncle为黑色 --- 旋转 + 变色
			else
			{
				if (cur == parent->_left) //单纯左边高
				{
					RotateR(grandfather); //右单旋

					//变色
					parent->_col = BLACK;
					grandfather->_col = RED;
				}
				else //cur是parent的右边
				{
					RotateLR(grandfather); //左右双旋

					//变色
					cur->_col = BLACK;
					grandfather->_col = RED;
				}
				break; //旋转+变色完之后, 该子树的根变成了黑色,无需继续调整
			}
		}

		else //父亲是爷爷的右孩子
		{
			Node* uncle = grandfather->_left;
			//1.插入节点的叔叔存在且为红色 --- 父亲和叔叔变黑,爷爷变红
			if (uncle && uncle->_col == RED)
			{
				parent->_col = uncle->_col = BLACK;
				grandfather->_col = RED;

				//调整完之后,更新cur, 判断是否还需要调整
				cur = grandfather;
				parent = cur->_parent;
			}
			//2.uncle不存在 / uncle为黑色 --- 旋转 + 变色
			else
			{
				if (cur == parent->_left) //cur是parent的左边,进行右单旋
				{
					RotateRL(grandfather); //右左单旋

					//变色
					cur->_col = BLACK;
					grandfather->_col = RED;
				}
				else //cur是parent的右边
				{
					RotateL(grandfather); //左单旋

					//变色
					grandfather->_col = RED;
					parent->_col = BLACK;
				}
				break; //旋转+变色完之后, 该子树的根变成了黑色,无需继续调整
			}
		}
	}

	_root->_col = BLACK;

	return true;
}

红黑树的验证

判断是否是红黑树

	bool IsRBTree()
	{
		if (_root == nullptr) return true;
		if (_root->_col == RED)
		{
			cout << "根节点为红色" << endl;
			return false;
		}

		//以最左路径的黑节点的个数作为参考值
		Node* cur = _root;
		int BlackCount = 0;
		while (cur)
		{
			if (cur->_col == BLACK)
				BlackCount++;
			cur = cur->_left;
		}

		//调用子函数判断红黑树
		int count = 0;
		return _IsRBTree(_root, count, BlackCount);
	}
private:
	bool _IsRBTree(Node* root, int count, int BlackCount)
	{
		if (root == nullptr)
		{
			if (count != BlackCount) 
			{
				cout << "黑色节点的个数不相等" << endl;
				return false;
			}
			return true;
		}

		//判断节点的孩子节点颜色不好判断, 转化成判断父亲节点颜色
		if (root->_col == RED && root->_parent->_col == RED)
		{
			cout << "存在连续的红节点" << endl;
			return false;
		}

		if (root->_col == BLACK)
			count++;

		//递归子问题
		return _IsRBTree(root->_left, count, BlackCount)
			&& _IsRBTree(root->_right, count, BlackCount);
	}

验证红黑树

#include "RBTree.h"

#include <vector>
void test1()
{
	int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
	RBTree<int, int> t;
	for (auto e : a)
	{
		t.Insert(make_pair(e, e));
	}

	t.IsRBTree();
	cout << t.IsRBTree() << endl;
}

void test2()
{
	const int N = 30;
	vector<int> v;
	v.reserve(N);
	srand(time(0));

	for (size_t i = 0; i < N; i++)
	{
		v.push_back(rand());
		cout << v.back() << endl;
	}

	RBTree<int, int> t;
	for (auto e : v)
	{
		t.Insert(make_pair(e, e));
		cout << "Insert:" << e << "->" << t.IsRBTree() << endl;
	}
	cout << t.IsRBTree() << endl;
}

int main()
{
	//test1();
	test2();
	return 0;
}

实现红黑树完整代码

#pragma once

#include <iostream>
using namespace std;

//颜色定义成枚举类型
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 _col;

	RBTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _col(RED)
	{}
};

template<class K, class V>
class RBTree
{
	typedef RBTreeNode<K, V> Node;
public:
	//红黑树中选择插入红色节点
	//插入黑色节点后所有路径的黑色节点数量都要变化,很麻烦~

	bool Insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			_root->_col = BLACK;
			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 && parent->_col == RED) //父亲不存在或者父亲为黑色就不需要继续调整了!
		{
			Node* grandfather = parent->_parent;
			if (grandfather->_left == parent) //父亲是爷爷的左孩子
			{
				Node* uncle = grandfather->_right;
				//1.插入节点的叔叔存在且为红色 --- 父亲和叔叔变黑,爷爷变红
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					//调整完之后,更新cur, 判断是否还需要调整
					cur = grandfather;
					parent = cur->_parent;
				}
				//2.uncle不存在 / uncle为黑色 --- 旋转 + 变色
				else
				{
					if (cur == parent->_left) //单纯左边高
					{
						RotateR(grandfather); //右单旋

						//变色
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else //cur是parent的右边
					{
						RotateLR(grandfather); //左右双旋

						//变色
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break; //旋转+变色完之后, 该子树的根变成了黑色,无需继续调整
				}
			}

			else //父亲是爷爷的右孩子
			{
				Node* uncle = grandfather->_left;
				//1.插入节点的叔叔存在且为红色 --- 父亲和叔叔变黑,爷爷变红
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					//调整完之后,更新cur, 判断是否还需要调整
					cur = grandfather;
					parent = cur->_parent;
				}
				//2.uncle不存在 / uncle为黑色 --- 旋转 + 变色
				else
				{
					if (cur == parent->_left) //cur是parent的左边,进行右单旋
					{
						RotateRL(grandfather); //右左单旋

						//变色
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					else //cur是parent的右边
					{
						RotateL(grandfather); //左单旋

						//变色
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					break; //旋转+变色完之后, 该子树的根变成了黑色,无需继续调整
				}
			}
		}

		_root->_col = BLACK;

		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 (parentParent == nullptr)
		{
			_root = subR;
			_root->_parent = nullptr;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}

			subR->_parent = parentParent;
		}
	}

	//右单旋
	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;

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

			subL->_parent = parentParent;
		}
	}

	//左右双旋
	void RotateLR(Node* parent)
	{
		RotateL(parent->_left);
		RotateR(parent);
	}

	//右左双旋
	void RotateRL(Node* parent)
	{
		RotateR(parent->_right);
		RotateL(parent);
	}

	//判断是否是红黑树
	bool IsRBTree()
	{
		if (_root == nullptr) return true;
		if (_root->_col == RED)
		{
			cout << "根节点为红色" << endl;
			return false;
		}

		//以最左路径的黑节点的个数作为参考值
		Node* cur = _root;
		int BlackCount = 0;
		while (cur)
		{
			if (cur->_col == BLACK)
				BlackCount++;
			cur = cur->_left;
		}

		//调用子函数判断红黑树
		int count = 0;
		return _IsRBTree(_root, count, BlackCount);
	}
private:
	bool _IsRBTree(Node* root, int count, int BlackCount)
	{
		if (root == nullptr)
		{
			if (count != BlackCount) 
			{
				cout << "黑色节点的个数不相等" << endl;
				return false;
			}
			return true;
		}

		//判断节点的孩子节点颜色不好判断, 转化成判断父亲节点颜色
		if (root->_col == RED && root->_parent->_col == RED)
		{
			cout << "存在连续的红节点" << endl;
			return false;
		}

		if (root->_col == BLACK)
			count++;

		//递归子问题
		return _IsRBTree(root->_left, count, BlackCount)
			&& _IsRBTree(root->_right, count, BlackCount);
	}

private:
	Node* _root = nullptr;
};

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

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

相关文章

You Only Cache Once:YOCO 基于Decoder-Decoder 的一个新的大语言模型架构

这是微软再5月刚刚发布的一篇论文提出了一种解码器-解码器架构YOCO&#xff0c;因为只缓存一次KV对&#xff0c;所以可以大量的节省内存。 以前的模型都是通过缓存先前计算的键/值向量&#xff0c;可以在当前生成步骤中重用它们。键值(KV)缓存避免了对每个词元再次编码的过程&…

基于SSM的“网约车用户服务平台”的设计与实现(源码+数据库+文档)

基于SSM的“网约车用户服务平台”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能 首页 站内新闻浏览 打车信息查询功能 在线打车功能…

Linux 服务器配置共享文件夹(NFS)

一、准备三台 linux 服务器 三台服务器: manger:172.16.11.178 ap1:172.16.11.179 ap2:172.16.11.180 /root/serverfiles/ 为共享目录 二、配置步骤 1、在服务端01的机器上安装nfs和rpcbind程序 yum -y install nfs* yum -y install rpcbind* 2、在安装完nfs以及rpcb…

MySQL查询篇-聚合函数-窗口函数

文章目录 distinct 关键字聚合函数常见的聚合函数group by和having 分组过滤 窗口函数with as窗口聚合函数排名窗口函数值窗口函数 distinct 关键字 distinct 去重数据&#xff0c;ps:null值也会查出来 select distinct column from table;聚合函数 常见的聚合函数 select …

【保姆级教程】VMware Workstation Pro的虚拟机导入vritualbox详细教程

解决方案 1、OVF格式2、VMX格式 1、OVF格式 选定需要导出的虚拟机&#xff08;关闭或者挂起状态下&#xff09;依次选择文件-导出为ovf 在Vritualbox导入刚刚导出的.ovf文件 更改路径&#xff0c;按实际需要修改 成功导入 2、VMX格式 如果在VMware Workstation Pro导出的…

rs6(vmp)瑞某,药某局,商某局,专某局,维某网,cookie + 后缀 的分析解析

文章目录 说在前面rs vmp 特征 介绍解决方法算法补环境运行报错 代码联调补环境框架 补环境导出结果导出cookie导出后缀 效果展示 vx lyj_txd qq 1416279170 # 加我备注来意说在前面 免责声明&#xff1a; 本篇文章只做学习讨论&#xff0c;无商务用途&#xff0c; 未对目标…

APP反抓包 - 服务端证书验证

案例引入: app:泡泡聊天 版本:v1.7.4 发送登录请求,抓包发现提示:403 Forbidden 这里就是使用了服务端证书校验,因为charles没有安装证书,所以到达服务器的响应没有通过验证,返回异常。 美之图: 一,校验逻辑 在安卓开发时,在客户端预设证书(p12/bks),客户端…

C++基础与深度解析 | C++初探 | Hello World | 系统I/O | 控制流 | 结构体与自定义数据类型

文章目录 一、从Hello World谈起二、系统I/O三、控制流四、结构体与自定义数据类型 一、从Hello World谈起 #include <iostream>void fun(const char *pInfo) {std::cout << pInfo << std::endl; }int main() {fun("Hello World!");fun("Hel…

从 Oracle 到 TiDB,国有大行打造本地生活 APP 新体验

导读 本文介绍了某国有大行推出的本地生活服务类 APP 在数字时代的创新应用实践。该 APP 利用金融科技和互联网平台模式&#xff0c;打造“金融非金融”的线上生态服务平台&#xff0c;满足了用户多样化的生活需求。为应对用户增长和数据量增加带来的挑战&#xff0c;该 APP 决…

【网络编程】Servlet的前后端练习 | 表白墙 | 前后端交互 | 提交消息 | 获取消息

文章目录 一、Servlet的前后端练习1.表白墙服务器要实现的逻辑&#xff1a;1.获取消息 &#xff1a;2.提交消息&#xff1a;完整前端代码&#xff1a;完整后端代码&#xff1a; 一、Servlet的前后端练习 1.表白墙 服务器要实现的逻辑&#xff1a; 1.页面加载时&#xff0c;网…

47-Qt控件详解:Buttons Containers1

一 QPushButton (命令按钮) #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QPushButton>//引入QPushButton类对应的头文件class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWind…

YOLOv8独家原创改进: AKConv(可改变核卷积)

1.AKConv原理介绍 地址:2311.11587 (arxiv.org) 摘要:基于卷积运算的神经网络在深度学习领域取得了令人瞩目的成果,但标准卷积运算存在两个固有的缺陷。一方面,卷积运算仅限于局部窗口,无法捕获其他位置的信息, 并且它的采样形状是固定的。 另一方面,卷积核的大小固定为…

vue3土味情话pinia可以持久保存再次修改App样式

我是不是你最疼爱的人-失去爱的城市 <template><div class"talk"><button click"getLoveTalk">土味情话</button><ul><li v-for"talk in talkStore.talkList" :key"talk.id">{{ talk.title }}<…

HarmonyOS开发案例:【UIAbility内和UIAbility间页面的跳转】

UIAbility内和UIAbility间页面的跳转&#xff08;ArkTS&#xff09; 介绍 基于Stage模型下的UIAbility开发&#xff0c;实现UIAbility内和UIAbility间页面的跳转。包含如下功能&#xff1a; UIAbility内页面的跳转。跳转到指定UIAbility的首页。跳转到指定UIAbility的指定页…

AtCoder Regular Contest 177 D. Earthquakes(概率 单调栈)

题目 D - Earthquakes 思路来源 官方题解 题解 对于不存在连锁反应的区间&#xff0c;每个区间独立处理&#xff0c;最后求个乘积 对于每个区间&#xff0c;相邻的两个杆子距离都小于H&#xff0c; 意味着没倒的区间是个连续的区间&#xff0c;假设要算i的概率 一定是第i…

软考144-下午题-【试题三】:UML图-类图、用例图

一、分值与目标 题型&#xff1a; 问题一~问题三&#xff08;扩展/UML——>设计模式&#xff09; 二、UML基础知识回顾 2-1、关系 UML中有四种关系&#xff1a;依赖、关联、泛化、实现。 1、关联 关联是一种结构关系&#xff0c;它描述了一组链&#xff0c;链是对象之间的…

Uniapp 自定义弹窗

布局 <view><view v-if"show" class"popup"><view class"popup-box"><view>支付方式:{{way}}</view><view>停车费用:{{money}}</view><view class"btn-box"><view class"ca…

修改el-checkbox样式

一定要在最外层&#xff1b; //未选中框/deep/ .el-checkbox__inner{border-color: #0862a3;}//选中框/deep/ .el-checkbox__input.is-checked .el-checkbox__inner{background-color: #0862a3;border-color: #0862a3;}//未选中框时右侧文字/deep/ .el-checkbox__label{}//选中…

虚拟化技术 挂载iSCSI网络存储器

一、实验内容 挂载iSCSI网络存储器到ESXi主机 二、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑&#xff0c;建议4C8G或以上配置已安装vSphere Client 三、实验步骤 1、挂载iSCSI网络存储器到ESXi主机 配置ESXi主机的虚拟网络 ESXi识别出三块…

【补充】图神经网络前传——DeepWalk

论文阅读 论文&#xff1a;https://arxiv.org/pdf/1403.6652 参考&#xff1a;【论文逐句精读】DeepWalk&#xff0c;随机游走实现图向量嵌入&#xff0c;自然语言处理与图的首次融合_随机游走图嵌入-CSDN博客 abstract DeepWalk是干什么的&#xff1a;在一个网络中学习顶点…