【数据结构】红黑树定义及基本操作

红黑树

红黑树基础定义

  1. 二叉搜索树,每个节点要么是黑节点,要么是红节点
  2. 每个节点到下面叶子节点的所有路径中,黑色节点的数量都相等
  3. 红色节点的子节点一定是黑色节点
  4. 根节点是黑色节点
  5. 叶子节点全是黑色节点。

其C语言的结构体定义如下

c 复制代码
typedef struct _rbtree_node {
	int key;
	void *val;
	
	struct _rbtree_node *parent;
	struct _rbtree_node *left;
	struct _rbtree_node *right;
	char color;
} rbtree_node;

typedef struct _rbtree {
	struct _rbtree_node *root;
	struct _rbtree_node *nil;  // 需要生成一个通用的黑色叶子节点,代表空,避免复杂的边界null处理
} rbtree;

红黑树插入新节点

红黑树左旋和右旋

红黑树的插入操作,需要定义左旋和右旋的操作。

从上图可以看出,左旋和右旋是可逆的操作,且不会改变节点的颜色。

  • 左旋代码(只有核心操作代码)
c 复制代码
void rbtree_left_rotation(rbtree *T, rbtree_node *x)
{
	
	rbtree_node *y = x->right;
	// 先把b节点放到x的右节点上
	x->right = y->left;
	if (y->left != T->nil) {
		y->left->parent = x;
	}
	
	// 再把y节点接到x的父节点上
	if (x->parent == T->nil) { // 此时x为根节点,所以parent是空
		T->root = y;
	} else if (x->parent-left == x) {
		x->parent->left = y;
	} else {
		x->parent->right = y;
	}
	y->parent = x->parent;

	// 再把x放到y的左节点上
	x->parent = y;
	y->left = x;
	
}
  • 右旋代码(把左旋代码中的x和y对调, left和right对调即可)
c 复制代码
void rbtree_right_rotation(rbtree *T, rbtree_node *y)
{
	rbtree_node *x = y->left;
	// 先把b节点放到y的左节点上
	y->left = x->right;
	if (x->right != T->nil) {
		x->right->parent = y;
	}
	
	// 再把x节点接到y的父节点上
	if (y->parent == T->nil) { // 此时x为根节点,所以parent是空
		T->root = x;
	} else if (y->parent-right == x) {
		y->parent->right = x;
	} else {
		y->parent->left = x;
	}
	x->parent = y->parent;

	// 再把y放到x的右节点上
	y->parent = x;
	x->right = y;
	
}
  • 插入代码
c 复制代码
void rbtree_insert_fixup(rbtree *T, rbtree_node *z)
{
	while (z->parent->color == RED) {
		if (z->parent == z->parent->parent->left) {
			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;
			} else {
				if (z == z->parent->right) {
					z = z->parent;
					rbtree_left_rotation(T, z);
				}
				
				z->parent->color = BLACK;
				z->parent->parent->color= RED;
				rbtree_right_rotation(T, z->parent);
				
			}
		}
		
	}

}

void rbtree_insert(rbtree *T, rbtree_node *z)
{
	rbtree_node *x = T->root;
	btree_node *y = T->nil;
	while (x != T->nil) {
		y = x;
		if (z->key < x->key) {
			x = x->left;
		} else if (z->key > x->key) {
			x = x->right;
		} else {
			return;
		}
	}

	if (y == T->nil) {
		T->root = z;
		return;
	}

	if (z->key > y->key) {
		y->right = z;
	} else {
		y->left = z;
	}
	z->parent = y;

	z->color = RED;
	rbtree_insert_fixup(T, z);
}
相关推荐
Logic1011 小时前
C语言/数据结构数位DP题解:平滑排列数字统计——区间内相邻位差不超过K的数字个数
c语言·数据结构·动态规划·时间复杂度·数位dp·算法题·前导零处理
wang09073 小时前
硬着头皮学数据结构和算法之Myers算法
数据结构·算法
垆边人似月.3 小时前
华为机试题 :最长递增子序列题目
数据结构·c++·算法·华为
yi01115 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
禾小西17 小时前
Redis 数据结构:快速的 Redis 有哪些慢操作?
数据结构·数据库·redis
H.莓飛18 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有18 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
chenbingjie_c19 小时前
C++ STL 适配器:stack & queue,从 vector/list 到 deque 深度解析
数据结构·c++
垆边人似月.1 天前
华为OD算法题:查找众数及中位数
数据结构·算法·leetcode
CoderYanger1 天前
一轮复习——F.动态规划模型总结(入门篇)
java·开发语言·数据结构·算法·leetcode·职场和发展·动态规划