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 红黑树的更多相关文章

  1. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  2. 谈c++ pb_ds库(二) 红黑树大法好

    厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...

  3. 红黑树(二)之 C语言的实现

    概要 红黑树在日常的使用中比较常用,例如Java的TreeMap和TreeSet,C++的STL,以及Linux内核中都有用到.之前写过一篇文章专门介绍红黑树的理论知识,本文将给出红黑数的C语言的实现 ...

  4. 大名鼎鼎的红黑树,你get了么?2-3树 绝对平衡 右旋转 左旋转 颜色反转

    前言 11.1新的一月加油!这个购物狂欢的季节,一看,已囊中羞涩!赶紧来恶补一下红黑树和2-3树吧!红黑树真的算是大名鼎鼎了吧?即使你不了解它,但一定听过吧?下面跟随我来揭开神秘的面纱吧! 一.2-3 ...

  5. 红黑树(R-B Tree)

    R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). ...

  6. 【红黑树】的详细实现(C++)

    红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键 ...

  7. 红黑树(四)之 C++的实现

    概要 前面分别介绍红黑树的理论知识和红黑树的C语言实现.本章是红黑树的C++实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章. 目录1. 红黑树的介绍2. 红黑树的C++ ...

  8. 红黑树(五)之 Java的实现

    概要 前面分别介绍红黑树的理论知识.红黑树的C语言和C++的实现.本章介绍红黑树的Java实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章.还是那句老话,红黑树的C/C+ ...

  9. 第十四章 红黑树——C++代码实现

    红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键 ...

随机推荐

  1. MFC记录

    1,下拉列表式组合框 合框被操作时会向父窗口发送通知消息,这些通知消息及其含义如下: CBN_CLOSEUP:组合框的列表框组件被关闭,简易组合框不会发送该通知消息       CBN_DBLCLK: ...

  2. 关于java、Android中Math的一些用法

    java.math.Math类常用的常量和方法: Math.PI 记录的圆周率Math.E记录e的常量Math.abs 求绝对值Math.sin 正弦函数 Math.asin 反正弦函数Math.co ...

  3. HTMLTestRunner生成空白resault.html

    发现一奇葩问题,用idle或pyscripter执行脚本,生成的是空白html,通过cmd,进入脚本目录执行python xx.py,却能生成测试报告. HTMLTestRunner 例子 #codi ...

  4. ubuntu14.04安装百度云Bcloud

    git地址:https://github.com/LiuLang/bcloud-packages sudo apt-get install python3-setuptools md5sum bclo ...

  5. db2官方SQLSTATE代码提示

    官网地址:http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/core/r0 ...

  6. 趣解curl

    Curl是Linux下一个很强大的http命令行工具,其功能十分强大. 1) 二话不说,先从这里开始吧! $ curl http://www.linuxidc.com 回车之后,www.linuxid ...

  7. JDBC基本知识

    JDBC的作用 JDBC为java访问数据库提供通用的API,可以为多种关系数据库提供统一访问.因为SQL是关系式数据库管理系统的标准语言,只要我们遵循SQL规范,那么我们写的代码既可以访问MySQL ...

  8. 【设计模式 - 13】之责任链模式(Chain Of Responsibility)

    1      模式简介 责任链模式的简介: 1.        责任链模式为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一 ...

  9. CSS3动画变形Animations

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. (使用步骤)ThinkPHP3.1.2中如何配置Ckeditor_4.1.1和Ckfindtor(转)

    ThinkPHP3.1.2中如何配置Ckeditor_4.1.1和Ckfindtor  一.下载Ckeditor和Ckfinder Ckeditor官网 http://ckeditor.com/dow ...