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

红黑树

红黑树基础定义

  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);
}
相关推荐
wangchunting3 小时前
数据结构-树
java·数据结构
Rabitebla3 小时前
归并排序(MergeSort)完全指南 —— 从原理到非递归实现
c语言·数据结构·c++·算法·排序算法
寒秋花开曾相惜3 小时前
(学习笔记)3.9 异质的数据结构(3.9.1 结构)
c语言·网络·数据结构·数据库·笔记·学习
Book思议-3 小时前
【数据结构】数组与特殊矩阵
数据结构·算法·矩阵
不吃蘑菇!3 小时前
LeetCode Hot 100-1(两数之和)
java·数据结构·算法·leetcode·哈希表
paeamecium3 小时前
【PAT甲级真题】- Linked List Sorting (25)
数据结构·c++·算法·pat考试·pat
Yupureki4 小时前
《Linux系统编程》19.线程同步与互斥
java·linux·服务器·c语言·开发语言·数据结构·c++
96774 小时前
C++ Lambda 表达式 匿名函数 sort
数据结构·c++·算法
liuyao_xianhui4 小时前
优选算法_锯齿形层序遍历二叉树_队列_C++
java·开发语言·数据结构·c++·算法·链表