一文速学---红黑树

文章目录

  • 一、红黑树简介
  • 二、 红黑树特性
  • 三、红黑树插入
    • 3.1 红黑树为空
    • 3.2 父节点为黑色
    • 3.3 父节点为红色
      • 3.3.1 父亲和叔叔都是红色
      • 3.3.2 父节点为红色,叔叔节点为黑色
        • 3.3.2.1 父节点在左节点,插入节点在父亲左节点
        • 3.3.2.2 父节点在左节点,插入节点在父亲右节点
        • 3.3.2.3 父节点在右节点,插入节点在父亲右节点
        • 3.3.2.4 父节点在右节点,插入节点在父亲左节点
  • 四、红黑树删除
    • 4.1 删除既有左子树又有右子树节点
    • 4.2 删除有左子树或者右子树节点
      • 4.2.1 不存在情况
      • 4.2.2 存在情况
      • 4.2.3 删除节点
    • 4.3 删除叶子节点
      • 4.3.1 叶子节点是红色
      • 4.3.2 叶子节点是黑色
        • 4.3.2.1 叶子节点是左节点,兄弟节点红色
        • 4.3.2.2 叶子节点是左节点,兄弟节点黑色
          • 4.3.2.2.1 兄弟节点右孩子为红色,左孩子任意颜色
          • 4.3.2.2.2 兄弟节点左孩子为红色,右孩子为黑色
          • 4.3.2.2.3 兄弟节点左右孩子为黑色
            • 父亲节点红色
            • 父亲节点黑色
        • 4.3.2.3 叶子节点是右节点,兄弟节点红色
        • 4.3.2.4 叶子节点是右节点,兄弟节点黑色
          • 4.3.2.4.1 兄弟节点左孩子为红色,右孩子任意颜色
          • 4.3.2.4.2 兄弟节点右孩子为红色,左孩子黑色
          • 4.3.2.4.3 兄弟节点左右孩子为黑色
            • 父亲节点红色
            • 父亲节点黑色
  • 五、红黑树查询
  • 六、红黑树中序遍历

一、红黑树简介

以前只是在考研学408的时候接触到红黑树,但是当时并没有做深入的了解。最近在做一个KV存储的项目,Key-Value的存储需要一个比数组更佳高效进行插入和删除的数据结构。红黑树,hash都是不错的用来存储的数据结构。

红黑树也是一种自平衡二叉查找树,它与AVL树类似,都在添加和删除的时候通过旋转操作保持二叉树的平衡,以求更高效的查询性能。

与AVL树相比,红黑树牺牲了部分平衡性,以换取插入/删除操作时较少的旋转操作,整体来说性能要优于AVL树。

二、 红黑树特性

红黑树是实际应用中最常用的平衡二叉查找树,它不严格的具有平衡属性,但平均的使用性能非常良好。

在红黑树中,节点被标记为红色和黑色两种颜色。

红黑树原则有以下几点:
1,根节点和叶节点一定是黑色(根叶黑)
2,从叶子到根的两个连续节点不能都是红色节点(不红红)
3,父节点的值大于左节点的值,小于右节点的值(左根右)
4,从任一节点到其他每个叶子的所有路径包含相同数目的黑色节点(黑路同)

三、红黑树插入

红黑树节点和树的结构体定义:

typedef struct _rbtree_node {
	unsigned char color;
	struct _rbtree_node *right;
	struct _rbtree_node *left;
	struct _rbtree_node *parent;
	KEY_TYPE key;
	void *value;
} rbtree_node;

typedef struct _rbtree {
	rbtree_node *root;
	rbtree_node *nil;
} rbtree;

因为父节点为黑色的概率较大,插入新节点为红色,可以避免颜色冲突,所以默认插入节点的颜色为红色

3.1 红黑树为空

直接插入节点,根据根叶黑的特性,设置为黑色

3.2 父节点为黑色

由于插入的是红色,不影响红黑树平衡
在这里插入图片描述

3.3 父节点为红色

因为父节点是红色,所以父节点不可能是根节点
父节点为红色时,会出现两种情况:1,叔叔为红色;2,叔叔为黑色;
在这里插入图片描述

3.3.1 父亲和叔叔都是红色

处理方式:
1,将M和N变黑,P变红;
2,将P设置为当前节点;
在这里插入图片描述
如果P的父节点是黑色则无需处理;如果P的父节点是红色,违反了不红红特性,继续调整;

3.3.2 父节点为红色,叔叔节点为黑色

3.3.2.1 父节点在左节点,插入节点在父亲左节点

这是一种插入后的LL型失衡
处理方式:
1,对P和M变色;
2,对P右旋;
在这里插入图片描述

3.3.2.2 父节点在左节点,插入节点在父亲右节点

这是一种插入后的LR型失衡
处理方式:
1,对M进行左旋;
2,将M设置为当前节点;
3,转换为 父节点在左节点,插入节点在父亲左节点 情况
在这里插入图片描述

3.3.2.3 父节点在右节点,插入节点在父亲右节点

这是一种插入后的RR型失衡
处理方式:
1,将M和P变色;
2,对P左旋;
在这里插入图片描述

3.3.2.4 父节点在右节点,插入节点在父亲左节点

这是一种插入后的RL型失衡
处理方式:
1,对M点右旋;
2,将M设置为当前节点;
3,转换为 父节点在右节点,插入节点在父亲左节点 情况
在这里插入图片描述
下面的代码是关于红黑树插入的实现:


//x为需要左旋的节点
void rbtree_left_rotate(rbtree *T, rbtree_node *x) {
	//支点
	rbtree_node *y = x->right;  // x  --> y  ,  y --> x,   right --> left,  left --> right

	//支点左节点赋给x右节点
	x->right = y->left; 
	if (y->left != T->nil) { //更改支点左节点的父节点
		y->left->parent = x;
	}

	y->parent = x->parent; //1 3
	if (x->parent == T->nil) { //x是root节点情况
		T->root = y;
	} else if (x == x->parent->left) {//x父节点的左孩子
		x->parent->left = y;
	} else {
		x->parent->right = y;
	}

	y->left = x; //1 5
	x->parent = y; //1 6
}

//y为需要右旋的节点
void rbtree_right_rotate(rbtree *T, rbtree_node *y) {
	//支点pivot
	rbtree_node *x = y->left;
	
	y->left = x->right;
	if (x->right != T->nil) {
		x->right->parent = y;
	}

	x->parent = y->parent;
	if (y->parent == T->nil) {//y是root情况
		T->root = x;
	} else if (y == y->parent->right) {//y是右孩子
		y->parent->right = x;
	} else {//y是左孩子
		y->parent->left = x;
	}

	x->right = y;
	y->parent = x;
}

void rbtree_insert_fixup(rbtree *T, rbtree_node *z) {
	//父亲节点如果是黑色,插入红色节点可以不变化
	while (z->parent->color == RED) { //z ---> RED
		//判断是爷爷节点的左边的L型还是右边的R型
		if (z->parent == z->parent->parent->left) {//L型
			//指向叔叔节点
			rbtree_node* y = z->parent->parent->right;
			//叔叔节点为红
			if (y->color == RED) {
				//变化叔叔,父亲,爷爷节点的颜色
				z->parent->color = BLACK;
				y->color = BLACK;
				z->parent->parent->color = RED;
				//将爷爷节点设置为当前节点
				z = z->parent->parent; //z --> RED
			} else {//叔叔节点为黑
				//将LR型转为LL型处理
				if (z == z->parent->right) {
					z = z->parent;	//这行代码用于当是LR型时,将z->parent设置为当前节点
					//对插入节点的父节点左旋
					rbtree_left_rotate(T, z);
				}
				//LL型
				z->parent->color = BLACK;
				z->parent->parent->color = RED;
				//将当前节点的爷爷节点右旋
				rbtree_right_rotate(T, z->parent->parent);
			}
		}
		else {//R型
			//指向叔叔节点
			rbtree_node *y = z->parent->parent->left;
			if (y->color == RED) {//叔叔节点为红色
				z->parent->color = BLACK;
				y->color = BLACK;
				z->parent->parent->color = RED;
				//将爷爷节点设置为当前节点
				z = z->parent->parent; //z --> RED
			} else {//叔叔节点为黑色
				if (z == z->parent->left) {//RL型
					//设置 z->parent为当前节点
					z = z->parent;
					//z->parent右转
					rbtree_right_rotate(T, z);
				}
				//RR型
				z->parent->color = BLACK;
				z->parent->parent->color = RED;
				//当前节点的爷爷节点左旋
				rbtree_left_rotate(T, z->parent->parent);
			}
		}
		
	}

	T->root->color = BLACK;
}


void rbtree_insert(rbtree *T, rbtree_node *z) {
	//指向叶节点
	rbtree_node* y = T->nil;
	//指向根节点
	rbtree_node* x = T->root;
	//y指向将要插入节点的父节点
	while (x != T->nil) {
		y = x;
		if (z->key < x->key) {
			x = x->left;
		} else if (z->key > x->key) {
			x = x->right;
		} else { //Exist
			return ;
		}
	}

	z->parent = y;
	if (y == T->nil) { //是否为空树
		T->root = z;
	} else if (z->key < y->key) { //插入左子树
		y->left = z;
	} else { //插入右子树
		y->right = z;
	}

	z->left = T->nil;
	z->right = T->nil;
	//将插入节点设置为红色
	z->color = RED;

	rbtree_insert_fixup(T, z);
}

四、红黑树删除

根据红黑树的性质,我们要删除的节点类型大致分为三种:

1,叶子节点
2,有左子树或者右子树节点
3,既有左子树又有右子树节点

4.1 删除既有左子树又有右子树节点

对于一棵普通二叉树来说,要删除既有左子树又有右子树的节点,我们首先要找到该节点的直接后继节点,然后用后继节点替换该节点,最后按1或2中的方法删除后继节点即可。所以情况3可以转换为情况1或2

对于红黑树来说,我们实际上删除的节点情况只有1和2。

4.2 删除有左子树或者右子树节点

4.2.1 不存在情况

情况二中有很多情况其实是不存在的,这些情况都违背了红黑树的性质(P代表需要删除的节点)
在这里插入图片描述
上面四种情况违背了黑路同的性质(P代表需要删除的节点)
在这里插入图片描述
上面两种情况违背了不红红的性质(P代表需要删除的节点)

4.2.2 存在情况

结合上面的分析,我们能发现对于只有左子树或者右子树的类型,其实只有下面的组合类型(P代表需要删除的节点)
在这里插入图片描述

4.2.3 删除节点

这两种情况的处理方法都是一样的,使用P的孩子M替换P,并且将M的颜色改为黑色即可。
在这里插入图片描述

4.3 删除叶子节点

4.3.1 叶子节点是红色

在这里插入图片描述
上面这两种情况都是一样的,直接删除P节点

4.3.2 叶子节点是黑色

4.3.2.1 叶子节点是左节点,兄弟节点红色

处理过程:
1,将父节点P和兄弟节点M交换颜色;(D是要删除节点,是当前节点)
2,对P左旋;
在这里插入图片描述
这个结果演变成后面讨论的兄弟节点是黑色情况(D是要删除节点)

4.3.2.2 叶子节点是左节点,兄弟节点黑色
4.3.2.2.1 兄弟节点右孩子为红色,左孩子任意颜色

白色表示红色或者黑色都可以
处理过程:(D是要删除节点,是当前节点)
1,P和M颜色对调
2,P进行左旋
3,删除D
4,MR设置为黑色
在这里插入图片描述

4.3.2.2.2 兄弟节点左孩子为红色,右孩子为黑色

白色表示红色或者黑色都可以
处理过程:(D是要删除节点,是当前节点)
1,ML和M颜色对调
2,M进行左旋
3,情况转换为 兄弟节点右孩子为红色,左孩子任意颜色
在这里插入图片描述

4.3.2.2.3 兄弟节点左右孩子为黑色
父亲节点红色

处理过程:(D是要删除节点,是当前节点)
1,P和M颜色对调
2,删除D
在这里插入图片描述

父亲节点黑色

处理过程:(D是要删除节点,是当前节点)
1,M颜色设置为红色
2,删除D
在这里插入图片描述

4.3.2.3 叶子节点是右节点,兄弟节点红色

处理过程:(D是要删除节点,是当前节点)
1,P和M颜色对调
2,P进行左旋
在这里插入图片描述
这个结果演变成后面讨论的兄弟节点是黑色情况(D是要删除节点)

4.3.2.4 叶子节点是右节点,兄弟节点黑色
4.3.2.4.1 兄弟节点左孩子为红色,右孩子任意颜色

处理过程:(D是要删除节点,是当前节点)
1,P和M颜色对调
2,P进行左旋
3,删除D
4,ML设置为黑色
在这里插入图片描述

4.3.2.4.2 兄弟节点右孩子为红色,左孩子黑色

白色表示红色或者黑色都可以
处理过程:(D是要删除节点,是当前节点)
1,MR和M颜色对调
2,M进行左旋
3,情况转换为 兄弟节点左孩子为红色,右孩子任意颜色
在这里插入图片描述

4.3.2.4.3 兄弟节点左右孩子为黑色
父亲节点红色

处理过程:(D是要删除节点,是当前节点)
1,P和M颜色对调
2,删除D
在这里插入图片描述

父亲节点黑色

处理过程:(D是要删除节点,是当前节点)
1,M颜色设置为红色
2,删除D
在这里插入图片描述

下面是实现红黑树删除的代码:

void rbtree_delete_fixup(rbtree *T, rbtree_node *x) {
	//对于有左子树或者右子树情况,因为只有黑红模式,所以传进来的x只能是红色
	//对于有左右子树情况可以转换为叶子结点或者只有左子树或者又子树情况
	//下面的循环主要用于处理叶子结点是黑色的情况且叶子节点的空节点不为根节点(代表树为空)
	while ((x != T->root) && (x->color == BLACK)) {
		//删除节点是左孩子
		if (x == x->parent->left) {
			//删除节点的兄弟节点
			rbtree_node *w= x->parent->right;
			if (w->color == RED) {//如果兄弟节点为红色
				//父节点和兄弟节点颜色互换
				w->color = BLACK;
				x->parent->color = RED;
				//父节点左旋
				rbtree_left_rotate(T, x->parent);
				//更新被删除节点的兄弟节点
				w = x->parent->right;
			}
			//兄弟节点为黑色,兄弟节点左右孩子都是黑色
			if ((w->left->color == BLACK) && (w->right->color == BLACK)) {
				//兄弟节点设置为红
				w->color = RED;
				//重新设置起始点点
				x = x->parent;
			} else {
				//兄弟节点为黑色,右孩子是黑色,左孩子红色---》右孩子变为红色
				if (w->right->color == BLACK) {
					//w和w的
					w->left->color = BLACK;
					w->color = RED;
					//兄弟节点右旋
					rbtree_right_rotate(T, w);
					//更新删除节点的兄弟节点
					w = x->parent->right;
				}
				//兄弟节点为黑色,右孩子为红色情况
				//兄弟节点和父节点颜色互换
				w->color = x->parent->color;
				x->parent->color = BLACK;
				//变换兄弟节点右孩子颜色
				w->right->color = BLACK;
				//对父节点做左旋
				rbtree_left_rotate(T, x->parent);
				//结束
				x = T->root;
			}
		//删除节点是右孩子
		} else {
			//删除节点的兄弟节点
			rbtree_node *w = x->parent->left;
			if (w->color == RED) {//如果兄弟节点为红色
				//父节点和兄弟节点颜色互换
				w->color = BLACK;
				x->parent->color = RED;
				//父节点右旋
				rbtree_right_rotate(T, x->parent);
				//更新被删除节点的兄弟节点
				w = x->parent->left;
			}
			//兄弟节点为黑色,兄弟节点左右孩子都是黑色
			if ((w->left->color == BLACK) && (w->right->color == BLACK)) {
				//兄弟节点设为红色
				w->color = RED;
				//重新设置起始点点
				x = x->parent;
			} else {
				//兄弟节点为黑色,左孩子是黑色,右孩子红色---》左孩子变为红色
				if (w->left->color == BLACK) {
					w->right->color = BLACK;
					w->color = RED;
					rbtree_left_rotate(T, w);
					w = x->parent->left;
				}
				//兄弟节点为黑色,左孩子为红色情况
				//兄弟节点和父节点颜色互换
				w->color = x->parent->color;
				x->parent->color = BLACK;
				w->left->color = BLACK;
				rbtree_right_rotate(T, x->parent);
				//结束
				x = T->root;
			}

		}
	}
	//设置为黑色
	x->color = BLACK;
}

rbtree_node *rbtree_delete(rbtree *T, rbtree_node *z) {
	//z指向想删除节点,y指向当前节点,x指向当前节点的孩子
	rbtree_node *y = T->nil;
	rbtree_node *x = T->nil;

	//z节点至多有一个孩子节点
	if ((z->left == T->nil) || (z->right == T->nil)) {
		y = z;//当前节点设置为要删除节点
	} else {//z节点有两个孩子节点
		y = rbtree_successor(T, z);//当前节点设置为后继节点
	}

	//双孩子改变后的当前点左右两个节点都是空节点
	if (y->left != T->nil) {//只有左孩子情况
		x = y->left;
	} else if (y->right != T->nil) {//只有右孩子情况
		x = y->right;
	}

	//直接使用平衡二叉树情况删除节点
	x->parent = y->parent;
	if (y->parent == T->nil) {
		T->root = x;
	} else if (y == y->parent->left) {
		y->parent->left = x;
	} else {
		y->parent->right = x;
	}
	
	if (y != z) {
		z->key = y->key;
		z->value = y->value;
	}
	//删除红色节点没有影响
	if (y->color == BLACK) {
		rbtree_delete_fixup(T, x);
	}

	return y;
}

五、红黑树查询

因为红黑树的性质中有左跟右,所以每次只需要和父节点比较大小即可,下面是查询实现代码:

rbtree_node *rbtree_search(rbtree *T, KEY_TYPE key) {

	rbtree_node *node = T->root;
	while (node != T->nil) {
		if (key < node->key) {
			node = node->left;
		} else if (key > node->key) {
			node = node->right;
		} else {
			return node;
		}	
	}
	return T->nil;
}

六、红黑树中序遍历

根据中序遍历的规则,实现中序遍历红黑树的代码

void rbtree_traversal(rbtree *T, rbtree_node *node) {
	if (node != T->nil) {
		rbtree_traversal(T, node->left);
		printf("key:%d, color:%d\n", node->key, node->color);
		rbtree_traversal(T, node->right);
	}
}

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

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

相关文章

学习日记_20241117_聚类方法(高斯混合模型)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

ISP——你可以从这里起步(二)

接上一篇&#xff0c;上一篇是原理篇&#xff0c;这一篇是实战篇&#xff0c;为了实现下面框图中的不完美ISP。 第一章 做一张RAW图自己用 不是所有的人都能获得raw图&#xff0c;即使获得了raw图也需要对应的sensor参数才能把它用起来&#xff0c;所以我找了一条野路子可以把…

shell bash---类似数组类型

0 Preface/Foreword C/C,Python&#xff0c;Java等编程语言&#xff0c;都含有数组类型&#xff0c;那么shell脚本是不是也有类似的语法呢&#xff1f; 1 类似数组类型 1.1 &#xff08;&#xff09;类似数组类型 #! /bin/bashecho "Welcome to bash world!" anim…

QT中使用图表之QChart绘制面积图

绘制面积图&#xff0c;则系列选择面积系列QAreaSeries 需要给系列设置上折线和下折线&#xff08;QLineSeries&#xff09;&#xff0c;如果没有设置下折线&#xff0c;则默认x轴为下折线 1、创建图表视图 //1、创建图表视图 QChartView * view new QChartView(this); //开…

H.265流媒体播放器EasyPlayer.js H.264/H.265播放器chrome无法访问更私有的地址是什么原因

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、MP3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方…

第02章 CentOS基本操作

2.文件基本操作【文件操作&#xff08;一&#xff09;】 目标 理解Linux下路径的表示方法能够使用命令(mkdir和touch)在指定位置创建目录和文件能够使用命令(rm)删除指定的目录和文件能够使用命令(ls)列出目录里的文件能够使用命令(cat,head,tail,less,more)查看文件内容理解标…

案例精选 | 某知名教育集团基于安全运营平台的全域威胁溯源实践

某知名教育集团成立于1999年&#xff0c;总部位于北京海淀中关村。集团专注于K-12基础教育&#xff0c;构建了从幼儿园到高中的全面教育体系&#xff0c;涵盖学校管理、教学科研、师资培训、信息化服务等多个方面。集团在全国范围内设有15所小学、12所初中、9所高中、6个国际部…

Java-01 深入浅出 MyBatis - MyBatis 概念 ORM映射关系 常见ORM 详细发展历史

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

nodejs和npm在gitbash中提示Not Found情况的解决办法

很多小伙伴学习了node以后&#xff0c;在cmd命令行中可以正常的获取node版本和npm版本&#xff0c;但是我们经常使用gitbash来管理git&#xff0c;这时候下载完gitbash后&#xff0c;在gitbash中输入node -v和npm -v会提示Not Found。这种情况如何处理&#xff1f;&#xff1f;…

Linux:调试器-gdb/cgdb

文章目录 一、编译成debug1、-g 选项 二、gdb调试命令1、在CentOS系统下检查安装gdb2、进入gdb模式3、quit 退出gdb4、list &#xff08;简写 l&#xff09;显示文件内容5、b 打断点6、 r / run运行程序7、c 让程序直接运行完 三、cgdb1、info b查看打的所有断点2、d 删除断点3…

数据结构 -- 二叉搜索树

二叉搜索树 概念 二叉搜索树又称为二叉排序树&#xff0c;它或为空树&#xff0c;或为具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于等于根节点的值。若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于等于根节…

VScode使用Batch Runner插件在终端运行bat文件

搜索并安装插件Batch Runner 创建测试文件 echo off echo "Hello world"按F5运行

4.STM32之通信接口《精讲》之USART通信---实验串口发送程序

本节将进行实战&#xff0c;基础了解请查看第1&#xff0c;2&#xff0c;3节&#xff08;Whappy&#xff09; 开始背&#xff01;&#xff01; USART ---》全双工 异步/同步 点对点 C语言基础printf用法&#xff0c;这节将用到printf的重定向&#xff0c;来打印到串口助手上…

特征融合篇 | CARAFE:轻量级通用上采样算子,可提高目标检测性能

前言:Hello大家好,我是小哥谈。CARAFE算子的主要特点是在保持轻量级功能的同时,能够提供比其他上采样算子更好的性能。它通过少量的参数和计算量来实现高效的图像上采样。CARAFE算子能够根据像素之间的关系进行自适应的上采样,从而更好地保留图像的细节和语义信息。🌈 …

游戏引擎学习第18天

clang-format 相关的配置可以参考下面 .clang-format 是用来配置代码格式化规则的文件&#xff0c;主要用于 Clang-Format 工具。以下是 .clang-format 文件中的一些常用设置&#xff1a; 1. 基础设置 Language: Cpp # 指定语言 (C, C, Java, JavaScript, etc…

递归(3)----力扣40组合数2,力扣473火柴拼正方形

给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含重复的组合。 示例 1: 输入: candidates [10,1,2,7,6,1…

SpringBoot Data Redis连接Redis-Cluster集群

使用SpringBoot Data Redis无法连接Redis-Cluster集群 最近在研究系统高并发下的缓存架构&#xff0c;因此自己在自己买的云服务器上搭建好Redis 5.0 版本的集群后&#xff0c;使用springboot的 RedisTemplate连接是发现总是访问不到集群节点。上网百度了发现没有好的解决办法&…

【插件】重复执行 pytest-repeat

安装 pip3 install pytest-repeat 用法 1.命令行 pytest --count num pytest --count 32.装饰器 pytest.mark.repeat(num) #num运行次数 pytest.mark.repeat(5)#执行结果如下&#xff1a;

强制放大缩小(适用于所有ctrl-,ctrl+)

以下操作&#xff1a; 使用资源管理器打开启动文件夹&#xff1a; 按下 Win R 键打开“运行”对话框。输入 shell:startup&#xff0c;然后按下 Enter。这应该会打开启动文件夹。 手动定位启动文件夹&#xff1a; 打开资源管理器并导航到以下路径&#xff1a; C:\Users\admin…

web前端开发网页--css样式的使用

1、css层叠性 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>css层叠性</title><style type"text/css">p{font-size: 12px;font-family: "微软雅黑";}.special{font-size: 24px;}#one{c…