当前位置: 首页 > ops >正文

数据结构---红黑树

红黑树(Red - Black Tree)

1.定义

红黑树是一种自平衡的二叉查找树,它在每一个节点上增加另一个存储位来表示节点的颜色,可以是红色或者黑色。通过这些颜色的约束,红黑树能够保证从根到叶子节点的最长路径不会超过最短路径的两倍,从而保持大致的平衡。

2.性质

1.节点是红色或者黑色。

2.根节点是黑色。

3.叶子节点(空节点)是黑色。

4.如果一个节点是红色,则它的两个子节点都是黑色。(不能有两个连续的红色节点)

5.从任意节点到其每个叶子的所有路径都包含相同数量的黑色节点。

以下是红黑树的简单实现代码(仅包含插入操作):

#include <iostream>
#include<vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;// 定义节点颜色
typedef enum { RED, BLACK } Color;// 定义红黑树节点
typedef struct RBTreeNode {int key;Color color;struct RBTreeNode* left;struct RBTreeNode* right;struct RBTreeNode* parent;
} RBTreeNode;// 创建新节点
RBTreeNode* createNode(int key) {RBTreeNode* newNode = (RBTreeNode*)malloc(sizeof(RBTreeNode));newNode->key = key;newNode->color = RED; // 新节点默认为红色newNode->left = NULL;newNode->right = NULL;newNode->parent = NULL;return newNode;
}// 左旋操作
void leftRotate(RBTreeNode** root, RBTreeNode* x) {RBTreeNode* y = x->right; // 设置yx->right = y->left; // 转移y的左子树到x的右子树if (y->left != NULL) {y->left->parent = x;}y->parent = x->parent; // 链接x的父节点到yif (x->parent == NULL) {*root = y;}else if (x == x->parent->left) {x->parent->left = y;}else {x->parent->right = y;}y->left = x; // 把x放到y的左子树x->parent = y;
}// 右旋操作
void rightRotate(RBTreeNode** root, RBTreeNode* y) {RBTreeNode* x = y->left; // 设置xy->left = x->right; // 转移x的右子树到y的左子树if (x->right != NULL) {x->right->parent = y;}x->parent = y->parent; // 链接y的父节点到xif (y->parent == NULL) {*root = x;}else if (y == y->parent->right) {y->parent->right = x;}else {y->parent->left = x;}x->right = y; // 把y放到x的右子树y->parent = x;
}// 修复插入操作后的红黑树性质
void fixInsert(RBTreeNode** root, RBTreeNode* newNode) {RBTreeNode* uncle;while (newNode != *root && newNode->parent->color == RED) {if (newNode->parent == newNode->parent->parent->left) {uncle = newNode->parent->parent->right; // 叔叔节点if (uncle != NULL && uncle->color == RED) {// 情况1:叔叔是红色newNode->parent->color = BLACK;uncle->color = BLACK;newNode->parent->parent->color = RED;newNode = newNode->parent->parent;}else {if (newNode == newNode->parent->right) {// 情况2:叔叔是黑色,且新节点是右孩子newNode = newNode->parent;leftRotate(root, newNode);}// 情况3:叔叔是黑色,且新节点是左孩子newNode->parent->color = BLACK;newNode->parent->parent->color = RED;rightRotate(root, newNode->parent->parent);}}else {uncle = newNode->parent->parent->left; // 叔叔节点if (uncle != NULL && uncle->color == RED) {// 情况1:叔叔是红色newNode->parent->color = BLACK;uncle->color = BLACK;newNode->parent->parent->color = RED;newNode = newNode->parent->parent;}else {if (newNode == newNode->parent->left) {// 情况2:叔叔是黑色,且新节点是左孩子newNode = newNode->parent;rightRotate(root, newNode);}// 情况3:叔叔是黑色,且新节点是右孩子newNode->parent->color = BLACK;newNode->parent->parent->color = RED;leftRotate(root, newNode->parent->parent);}}}(*root)->color = BLACK; // 根节点必须是黑色
}// 插入新节点
void insert(RBTreeNode** root, int key) {RBTreeNode* newNode = createNode(key);RBTreeNode* current = *root;RBTreeNode* parent = NULL;// 查找插入位置while (current != NULL) {parent = current;if (newNode->key < current->key) {current = current->left;}else {current = current->right;}}newNode->parent = parent; // 设置父节点if (parent == NULL) {*root = newNode; // 如果树为空,新节点成为根节点}else if (newNode->key < parent->key) {parent->left = newNode; // 插入到父节点的左子树}else {parent->right = newNode; // 插入到父节点的右子树}fixInsert(root, newNode); // 修复红黑树性质
}// 打印红黑树(中序遍历)
void inorderTraversal(RBTreeNode* root) 
{if (root != NULL) {inorderTraversal(root->left);printf("%d(%s) ", root->key, root->color == RED ? "RED" : "BLACK");inorderTraversal(root->right);}
}int main() 
{RBTreeNode* root = NULL;insert(&root, 10);insert(&root, 20);insert(&root, 30);insert(&root, 40);insert(&root, 50);printf("Inorder traversal of the constructed Red - Black Tree is:\n");inorderTraversal(root);printf("\n");return 0;
}

代码运行结果:

微信截图_20250608122112

说明:以上代码来自于Kimi AI助手。

好文链接:

数据结构(8)-- 图解红黑树

【高阶数据结构】红黑树详解

http://www.xdnf.cn/news/12712.html

相关文章:

  • 【大模型LLM学习】function call/agent学习记录
  • Windows开机自动启动中间件
  • CAD多面体密堆积3D插件
  • Maven的使用
  • Mac M芯片 RAG 极简流程 安装 ragflow + LM studio
  • Java 高级泛型实战:8 个场景化编程技巧
  • 0x-4-Oracle 23 ai-sqlcl 25.1.1 独立安装-配置和优化
  • OD 算法题 B卷【正整数到Excel编号之间的转换】
  • Web后端开发(请求、响应)
  • SpringCloud2025+SpringBoot3.5.0+gateway+webflux子服务路由报503
  • Pinocchio 库详解及其在足式机器人上的应用
  • 板凳-------Mysql cookbook学习 (十--2)
  • Linux权限探秘:驾驭权限模型,筑牢系统安全
  • 【PyCharm必会基础】正确移除解释器及虚拟环境(以 Poetry 为例 )
  • 2025新高考二卷选择题第一题题解
  • 嵌入式全栈面试指南:TCP/IP、C 语言基础、STM32 外设与 RT‑Thread
  • MATLAB遍历生成20到1000个节点的无线通信网络拓扑推理数据
  • 大实验:基于赛灵思csg324100T,pmodMAXsonar的危险距离警报
  • [论文阅读] 人工智能+软件工程 | 结对编程中的知识转移新图景
  • 基于贝叶斯网络构建结构方程_TomatoSCI分析日记
  • Qwen系列之Qwen3解读:最强开源模型的细节拆解
  • 计数排序_桶排序
  • 从 Vue 2.0 进阶到 Vue 3.0 的核心技术解析指南
  • **解锁 C++ std::map 的力量**
  • android 布局小知识点 随记
  • OpenEuler服务器警告邮件自动化发送:原理、配置与安全实践
  • 数据的输出、输入
  • 20242817李臻-安全文件传输系统-项目验收
  • springboot2.x升级springboot3.x
  • 端午编程小游戏--艾草驱邪