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

C++--红黑树

1.什么是红黑树

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

 性质:

1. 每个结点不是红色就是黑色。
2. 根节点是黑色的。
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的,即红色不能连续。
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点,即每条路径黑色节点相同。
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

注意:黑色节点相同,红色节点不连续,所以最长路径中节点个数不会超过最短路径节点个数的两倍。

2.红黑树的插入实现

由于红黑树是一颗二叉平衡搜索树,所以它的性质和AVL树差不多(AVL树的特性:左右子树高度差的绝对值不超过一)。

红黑树的插入可以分为两部分:按照二叉搜索树的规则插入新节点,然后判断是否需要旋转交换和改变颜色。

检测新节点的插入,需要判断是否破坏了红黑树的性质,因为新节点的默认颜色是红色,因此:如果其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质三不能有连在一起的红色节点,此时需要对红黑树分情况来讨论。

插入代码的实现:

#pragma once
using namespace std;
#include <assert.h>
namespace sss
{enum Color{red,black};template<class K,class V>struct RedBlackTreeNode{RedBlackTreeNode<K,V>* _left;RedBlackTreeNode<K, V>* _right;RedBlackTreeNode<K, V>* _parent;pair<K, V> _date;Color _col;RedBlackTreeNode(const pair<K, V>& date=make_pair(0,0)):_left(nullptr),_right(nullptr),_parent(nullptr),_date(date)//, _col(black){}};template<class K, class V>class RedBlackTree{typedef RedBlackTreeNode<K, V> Node;public:typedef RedBlackTree Tree;bool insert(const pair<K, V>& date){if (_root == nullptr){_root = new Node(date);_root->_col = black;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_date< date){parent = cur;cur = cur->_right;}else if (cur->_date> date){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(date);cur->_col = red;if (parent->_date.first < date. first){parent->_right = cur;}else {parent->_left = cur;}cur->_parent = parent;//Node* uncle=parent->_parent->while (parent && parent->_col == red){Node* grandfater = parent->_parent;assert(grandfater);assert(grandfater->_col==black);if (parent == grandfater->_left){Node* uncle = grandfater->_right;// 情况一 : uncle存在且为红,变色+继续往上处理if (uncle && uncle->_col == red){parent->_col = uncle->_col = black;grandfater->_col = red;// 继续往上处理cur = grandfater;parent = cur->_parent;}// 情况二+三:uncle不存在 + 存在且为黑else{// 情况二:右单旋+变色//     g //   p   u// cif (cur == parent->_left){RotateR(grandfater);parent->_col = black;grandfater->_col = red;}else{// 情况三:左右单旋+变色//     g //   p   u//     cRotateL(parent);RotateR(grandfater);cur->_col = black;grandfater->_col = red;}break;}}else{Node* uncle = grandfater->_left;// 情况一if (uncle && uncle->_col == red){parent->_col = uncle->_col = black;grandfater->_col = red;// 继续往上处理cur = grandfater;parent = cur->_parent;}else{// 情况二:左单旋+变色//     g //   u   p//         cif (cur == parent->_right){RotateL(grandfater);parent->_col = black;grandfater->_col = red;}else{// 情况三:右左单旋+变色//     g //   u   p//     cRotateR(parent);RotateL(grandfater);cur->_col = black;grandfater->_col = red;}break;}}}_root->_col = black;return true;}void Inorder(){_Inorder(_root);}private://右旋void RotateR(Node* parent){Node* subl = parent->_left;Node* sublr = subl->_right;Node* prev = parent->_parent;parent->_left = sublr;if (sublr)sublr->_parent = parent;parent->_parent = subl;subl->_right = parent;if (_root == parent){_root = subl;subl->_parent = nullptr;}else{if (prev->_left == parent){subl->_parent = prev;prev->_left = subl;}else{subl->_parent = prev;prev->_right = subl;}}}//左旋void RotateL(Node* parent){Node* subr = parent->_right;Node* subrl = subr->_left;Node* prev = parent->_parent;parent->_right = subrl;if (subrl)subrl->_parent = parent;subr->_left = parent;parent->_parent = subr;if (_root == parent){_root = subr;subr->_parent = nullptr;}else{if (prev->_left == parent){subr->_parent = prev;prev->_left = subr;}else{subr->_parent = prev;prev->_right = subr;}}}void _Inorder(Node* _root){if (_root == nullptr)return;_Inorder(_root->_left);cout << _root->_date.first << " " << _root->_date.second << endl;_Inorder(_root->_right);}private:Node* _root = nullptr;};}


 

http://www.lryc.cn/news/129409.html

相关文章:

  • Unity 找不到 Navigation 组件的解决
  • 【js】时间和时间戳转换、日期格式化
  • glog体验第一天(0)glog介绍和安装
  • Android 13像Settings一样获取SIM卡信息
  • Can‘t find end of central directory : is this a zip file ? at XMLHttpRequest
  • 基于SpringBoot+Thymeleaf仓库管理系统
  • ubuntu20.04磁盘满了 /dev/mapper/ubuntu--vg-ubuntu--lv 占用 100%
  • 【制作npm包4】api-extractor 学习
  • 神经网络基础-神经网络补充概念-52-正则化网络的激活函数
  • 代码随想录训练营day56| 583. 两个字符串的删除操作 72. 编辑距离
  • 神经网络基础-神经网络补充概念-55-为什么是ML策略
  • C++初阶语法——内部类
  • Java基础(十四)面向对象编程 OOP 多态
  • 【Android】解决Lint found fatal errors while assembling a release target
  • CF1195E OpenStreetMap 题解
  • 微信营销系统如何使用效果会更好
  • Linux开机启动程序添加root权限
  • 安卓13解决链接问题
  • ​《乡村振兴战略下传统村落文化旅游设计 》在2023年畅销榜排名465位
  • 实现一个自动保存高CPU占用现场的简易工具
  • 易服客工作室:如何在WordPress网站中举办虚拟活动
  • Java IO流(一)IO基础
  • 区间覆盖 线段覆盖 二分
  • F#奇妙游(20):主动模式
  • OLED透明屏与传统显示屏的区别:探索未来视觉体验的新里程碑
  • 打开软件提示mfc100u.dll缺失是什么意思?要怎么处理?
  • Python 基础 -- Tutorial(二)
  • 11 迭代器|生成器|协程
  • “第三方支付”详解!
  • Rust之泛型、trait与生命周期