平衡搜索树(二) Rb 红黑树
Rb树简介
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单 路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。(性质3、性质4保证了红黑树最长的路径不超过最短路径的两倍)
如图所示:
红黑树是满足下面红黑性质的二叉搜索树
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
好,现在了解了红黑树的特性之后,我们来开始创建红黑树。
- //红黑树的节点的结构
- template<class K,class V>
- struct RedBlaceTreeNode
- {
- typedef RedBlaceTreeNode<K, V> Node;
- RedBlaceTreeNode(const K& key,const V& value)
- :_left(NULL), _right(NULL), _parent(NULL)
- , _key(key), _value(value), _col(RED)
- {}
- Node* _left;
- Node* _right;
- Node* _parent;
- K _key;
- V _value;
- Sign _col;
- };
//红黑树的结构
- template<class K,class V>
- class RedBlaceTree
- {
- typedef RedBlaceTreeNode<K, V> Node;
- public:
- RedBlaceTree()
- :_root(NULL)
- {}
- public:
- bool _Push(const K& key, const V& value);
- void _LeftSpin(Node*& parent);
- void _RightSpin(Node*& parent);
- void _LeftRightSpin(Node*& parent);
- void _RightLeftSpin(Node*& parent);
- /*Check*/
- //1. 每个节点,不是红色就是黑色的
- //2. 根节点是黑色的
- //3. 如果一个节点是红色的,则它的两个子节点是黑色的
- //4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点
- void _Inorder(){ Inorder(_root); }
- void Inorder(Node* root);
- protected:
- Node* _root;
- };
//创建红黑树的函数 _Push()
插入的几种情况
cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点
1.第一种情况 cur为红,p为红,g为黑,u存在且为红 则将p,u改为黑,g改为红,然后把g当成cur,继续向上调整。( 还挺简单 O(∩_∩)O 继续往下看↓↓)
2.第二种情况 cur为红,p为红,g为黑,u不存在/u为黑 p为g的左孩子,cur为p的左孩子,则进行右单旋转;相反,p为g的右孩子,cur为p的右孩子,则进行左单旋转 p、g变色--p变黑,g变红
3.第三种情况 cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转 则转换成了情况2
- template<class K, class V>
- bool RedBlaceTree<K, V>::_Push(const K& key, const V& value)
- {
- Node* cur = _root;
- Node* parent = NULL;
- if (_root == NULL)
- {
- _root = new Node(key, value);
- _root->_col = BLACK;
- }
- else
- {
- while (cur)
- {
- parent = cur;
- if (key > cur->_key)
- {
- cur = cur->_right;
- }
- else if (key < cur->_key)
- {
- cur = cur->_left;
- }
- else
- {
- return false;
- }
- }
- cur = new Node(key, value);
- if (key > parent->_key)
- {
- parent->_right = cur;
- cur->_parent = parent;
- }
- else
- {
- parent->_left = cur;
- cur->_parent = parent;
- }
- if (parent->_col == RED) //如果父亲节点为红色就需要调整
- {
- bool sign = false; //标记位,用来标记grandparent是否为根节点
- while (cur->_parent)
- {
- Node* grandparent = NULL;
- Node* uncle = NULL;
- parent = cur->_parent;
- grandparent = parent->_parent;
- if (grandparent) //如果祖父节点存在
- {
- if (grandparent == _root)
- {
- sign = true; //标记祖父节点是否为根节点
- }
- if (parent->_key > grandparent->_key) //确定叔父节点
- {
- uncle = grandparent->_left;
- }
- else
- {
- uncle = grandparent->_right;
- }
- //第一种情况:cur为红,p为红,g为黑,u存在且为红
- if (uncle && uncle->_col == RED)
- {
- parent->_col = BLACK;
- uncle->_col = BLACK;
- grandparent->_col = RED;
- if (sign)
- {
- break;
- }
- cur = grandparent;
- }
- //第二种情况:cur为红,p为红,g为黑,u不存在/u为黑(单旋)
- //第三种情况:cur为红,p为红,g为黑,u不存在/u为黑(双旋)
- else
- {
- //第二
- if (grandparent->_left == parent && parent->_left == cur)
- {
- grandparent->_col = RED;
- parent->_col = BLACK;
- _RightSpin(grandparent);
- if (sign)
- {
- _root = grandparent;
- }
- break;
- }
- else if (grandparent->_right == parent && parent->_right == cur)
- {
- grandparent->_col = RED;
- parent->_col = BLACK;
- _LeftSpin(grandparent);
- if (sign)
- {
- _root = grandparent;
- }
- break;
- }
- //第三
- else if (grandparent->_left == parent && parent->_right == cur)
- {
- grandparent->_col = RED;
- cur->_col = BLACK;
- _LeftRightSpin(grandparent);
- if (sign)
- {
- _root = grandparent;
- }
- break;
- }
- else if (grandparent->_right == parent && parent->_left == cur)
- {
- grandparent->_col = RED;
- cur->_col = BLACK;
- _RightLeftSpin(grandparent);
- if (sign)
- {
- _root = grandparent;
- }
- break;
- }
- }
- }
- else //cur 的上面只有一层
- {
- break;
- }
- }
- }
- }
- _root->_col = BLACK;
- }
平衡搜索树(二) Rb 红黑树的更多相关文章
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树
http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...
- 谈c++ pb_ds库(二) 红黑树大法好
厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...
- 红黑树(二)之 C语言的实现
概要 红黑树在日常的使用中比较常用,例如Java的TreeMap和TreeSet,C++的STL,以及Linux内核中都有用到.之前写过一篇文章专门介绍红黑树的理论知识,本文将给出红黑数的C语言的实现 ...
- 大名鼎鼎的红黑树,你get了么?2-3树 绝对平衡 右旋转 左旋转 颜色反转
前言 11.1新的一月加油!这个购物狂欢的季节,一看,已囊中羞涩!赶紧来恶补一下红黑树和2-3树吧!红黑树真的算是大名鼎鼎了吧?即使你不了解它,但一定听过吧?下面跟随我来揭开神秘的面纱吧! 一.2-3 ...
- 红黑树(R-B Tree)
R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). ...
- 【红黑树】的详细实现(C++)
红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键 ...
- 红黑树(四)之 C++的实现
概要 前面分别介绍红黑树的理论知识和红黑树的C语言实现.本章是红黑树的C++实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章. 目录1. 红黑树的介绍2. 红黑树的C++ ...
- 红黑树(五)之 Java的实现
概要 前面分别介绍红黑树的理论知识.红黑树的C语言和C++的实现.本章介绍红黑树的Java实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章.还是那句老话,红黑树的C/C+ ...
- 第十四章 红黑树——C++代码实现
红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键 ...
随机推荐
- Linux Shell编程(19)——测试与分支
case和select结构在技术上说不是循环,因为它们并不对可执行的代码块进行迭代.但是和循环相似的是,它们也依靠在代码块的顶部或底部的条件判断来决定程序的分支.在代码块中控制程序分支case (in ...
- 利用python分析nginx日志
最近在学习python,写了个脚本分析nginx日志,练练手.写得比较粗糙,但基本功能可以实现. 脚本功能:查找出当天访问次数前十位的IP,并获取该IP来源,并将分析结果发送邮件到指定邮箱. 实现前两 ...
- intellij idea 2016版破解方法
之前办法不能用了,现在最新方法,打开http://idea.lanyus.com,直接获取验证码即可
- C++Primer第5版学习笔记(三)
C++Primer第5版学习笔记(三) 第四/五章的重难点内容 你可以点击这里回顾第三章内容 因为第五章的内容比较少,因此和第四章的笔记内容合并. 第四章是 ...
- A*寻路算法的探寻与改良(一)
A*寻路算法的探寻与改良(一) by:田宇轩 第一部分:这里我们主 ...
- sqlplus乱码
使用SecureCRT或是pietty_ch连接到一台安装有Oracle DB 10g的RHEL4.2的机器,linux使用的shell是默认的bash. 在bash提示符下,使用Del键或者Back ...
- 20个 Unix/Linux 命令技巧
让我们用这些Unix/Linux命令技巧开启新的一年,提高在终端下的生产力.我已经找了很久了,现在就与你们分享. 删除一个大文件 我在生产服务器上有一个很大的200GB的日志文件需要删除.我的rm和l ...
- 402. Remove K Digits
(English version is after the code part) 这个题做起来比看起来容易,然后我也没仔细想,先速度刷完,以后再看有没有改进. 用这个来说: 1 2 4 3 2 2 1 ...
- SQL 查询条件放在LEFT OUTER JOIN 的ON语句后与放在WHERE中的区别
这两种条件放置的位置不同很容易让人造成混淆,以致经常查询出莫名其妙的结果出来,特别是副本的条件与主表不匹配时,下面以A,B表为例简单说下我的理解. 首先要明白的是: 跟在ON 后面的条件是对参与左联接 ...
- BZOJ 1835: [ZJOI2010]base 基站选址 [序列DP 线段树]
1835: [ZJOI2010]base 基站选址 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立 ...