平衡搜索树(二) 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),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键 ...
随机推荐
- SqlServer:CTE函数处理递归(WITH语法)
我们在做分类处理的时候,总会遇到递归的处理,比如说地区就是一个例子,中国--北京--西城区,我们可以把这样的信息存储在一个数据表中,用ParentID区分根节点和叶子节点.假如我们要做导航,得到了”西 ...
- Shadow Register 是什么?
ARM处理器有个Shadow Register的概念,查了很多资料,语焉不详,究竟是什么意思呢? 这其实是个和硬件有关的概念. 有些register是2层的,第一层是供CPU访问,第二层供Hw访问. ...
- Struts1、Struts2和SpringMVC剖析【转载】
前段框架用了不少,今天就来做个总结.网上关于Struts1.Struts2.SpringMVC的文章有很多,这里的内容就是基于它们,来做个比较. 这三个框架是按照上面的顺序,依次出现的,它们都是对MV ...
- 《University Calculus》-chape4-极坐标与圆锥曲线-极坐标系下的面积与弧长
极坐标系下的面积: 在直角坐标系下一样,这里在极坐标系下,我们面临一个同样的问题:如何求解一个曲线围成的面积?虽然两种情况本质上是一样的,但是还是存在一些细小的区别. 在直角坐标系下中,我们是讨论一条 ...
- OracleL
DDL : Data Definition Language (DDL) statements are used to define the database structure or schema ...
- Hadoop Hive概念学习系列之什么是Hive?(一)
参考 <Hadoop大数据分析与挖掘实战>的在线电子书阅读 http://yuedu.baidu.com/ebook/d128cf8e33687e21 ...
- C#在ASP.NET4.5框架下的首次网页应用
运行效果预览: 先看实践应用要求: 1.编写一个函数,用于计算1!+2!+3!+4!+5!,在控制台或页面输出运行结果. 2.在控制台或页面输出九九乘法表. 3.输入10个以内的整数,输出该组整数的降 ...
- nORA-01000: 超出打开游标的最大数(SDE连接)
1.运行ArcObjects代码报错: IFeatureCursor pCursor = null; try { pCursor = m_pCatchLayer.m_pFeatureClass.Sea ...
- C语言学习_C如何在一个文件里调用另一个源文件中的函数
问题 C如何在一个文件里调用另一个源文件中的函数,如题. 解决办法 当程序大了代码多了之后,想模块化开发,不同文件中存一点,是很好的解决办法,那我们如何做才能让各个文件中的代码协同工作呢?我们知道,m ...
- winform Execl数据 导入到数据库(SQL) 分类: WinForm C# 2014-05-09 20:52 191人阅读 评论(0) 收藏
首先,看一下我的窗体设计: 要插入的Excel表: 编码 名称 联系人 电话 省市 备注 100 100线 张三 12345678910 北京 测试 101 101线 张三 12345678910 上 ...