【C语言】红黑树

红黑树

1.二叉查找树

首先要了解的是二叉查找树,也称为二叉排序树,优点是在节点均匀分布的情况下,查找效率更高,缺点是,如果节点分布在一侧,查找时间就会约等于数组从头到尾的去查找。

  • 二叉查找树的子树都是二叉查找树。
  • 左子树都小于根节点,右子树都大于根节点

2.平衡二叉查找树

其次,平衡二叉查找树,也称为AVL树,AVL是它的两个发明者的名字组成。它有一套插入,删除的平衡机制,让插入删除后使用相应的平衡算法,再次成为AVL树,这样可以让每次的最坏查找时间接近O(logn),缺点是用于平衡的开销太大。

  • AVL树的子树都是AVL树
  • 左右子树的高度差小于等于1

3.红黑树

红黑树(Red Black Tree)是一种 二叉查找树,它并不是严格意义上的平衡二叉树,因为它有自己的平衡规则,和平衡二叉树规则不一样。它的查找,插入,删除的时间复杂度都是O(logn),n是指树中元素的个数。因此它在查找,插入,删除的最坏情况下运行时间很好。

​ 为什么查找,插入,删除的复杂度都是O(logn),因为红黑树自己有一套规则,去保持红黑树插入删除后还是红黑树。红黑树的平衡次数,相对于普通平衡二叉树少,开销更小。

  • 结点是红色或黑色(一个节点要么是红色,要么是黑色)
  • 根结点是黑色
  • 所有叶子都是黑色。(叶子是NIL结点)
  • 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
  • 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

红黑树用在哪些地方:hashmap,cfs,epoll,定时器,nginx中

使用红黑树,

​ 第一,主要是使用它的(key,value)属性,使用key可以去树上查找相应的value

​ 第二,它是一个二叉排序树,中序遍历是顺序的,可以查一个范围,例如比某个key小的有哪些

1.定义一颗红黑树

c 复制代码
typedef int KEY_TYPE;
//定义红黑树节点
typedef struct _rbtree_node
{
	KEY_TYPE key;
	void *value;
	struct _rbtree_node *right;
	struct _rbtree_node *left;
	struct _rbtree_node *parent;
	unsigned char color;
} rbtree_node;

//定义红黑树
typedef struct _rbtree
{
    //红黑树的根
	rbtree_node *root;
    //红黑树叶子节点
	rbtree_node *nil;
} rbtree;

2. 红黑树旋转

红黑树的插入,删除,会导致不平衡,需要旋转和变色

2.1 左旋

这里仅仅是旋转,是因为不满足上述5条红黑树性质而进行的旋转。与平衡二叉树的旋转不一样。

因此,只需要考虑旋转点与它的父节点之间的左旋。

c 复制代码
// T是树根节点,x是旋转轴节点的父节点
void rbtree_left_rotate(rbtree *T, rbtree_node *x)
{
	//y为旋转轴节点
	rbtree_node *y = x->right; 

	x->right = y->left;
	if (y->left != T->nil)
	{
		y->left->parent = x;
	}

	y->parent = x->parent; 
	if (x->parent == T->nil)
	{
		T->root = y;
	}
	else if (x == x->parent->left)
	{
		x->parent->left = y;
	}
	else
	{
		x->parent->right = y;
	}

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

2.2 右旋

将左旋代码的x改为y,left改为right即可

推荐一个零声教育学习教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:链接

相关推荐
蒟蒻的贤7 分钟前
Web APIs 第二天
开发语言·前端·javascript
ljp_nan14 分钟前
QT --- 初识QT
开发语言·qt
ᅠᅠᅠ@19 分钟前
异常枚举;
开发语言·javascript·ecmascript
凌肖战25 分钟前
力扣上刷题之C语言实现(数组)
c语言·算法·leetcode
编程版小新25 分钟前
C++初阶:STL详解(四)——vector迭代器失效问题
开发语言·c++·迭代器·vector·迭代器失效
c4fx1 小时前
Delphi5利用DLL实现窗体的重用
开发语言·delphi·dll
鸽芷咕1 小时前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
Jhxbdks1 小时前
C语言中的一些小知识(二)
c语言·开发语言·笔记
java6666688881 小时前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存1 小时前
源码分析:LinkedList
java·开发语言