#ifndef __RED_BLACK_TREE_H__
#define __RED_BLACK_TREE_H__ namespace lxf {
template <typename Key, typename Value>
class RedBlackTree {
struct Node {
enum Color { RED, BLACK };
Key key;
Value value;
Node *left;
Node *right;
Node *parent;
Color color;
Node(Key pkey, Value pvalue, Color pcolor) : key(pkey), value(pvalue), left(nullptr), right(nullptr), parent(nullptr), color(pcolor) {}
};
Node *root;
void rotateLeft(Node *x);
void rotateRight(Node *x); Node* deleteMin(Node* head);
Node* min(Node *head);
public:
void insert(Key key, Value value);
void erase(Key key);
RedBlackTree():root(nullptr) {}
}; /*
* 对红黑树的节点(x)进行左旋转
*
* 左旋示意图(对节点x进行左旋):
* px px
* / /
* x y
* / \ --(左旋)--> / \ #
* lx y x ry
* / \ / \
* ly ry lx ly
*
*
*/
template<typename Key, typename Value>
inline void RedBlackTree<Key, Value>::rotateLeft(Node * x)
{
Node *y = x->right; x->right = y->left;
if (y->left != nullptr)
y->left->parent = x; y->parent = x->parent;
if (x->parent == nullptr)
root = y;
else {
if (x->parent->left == x)
x->parent->left = y;
else
x->parent->right = y;
}
y->left = x;
x->parent = y;
} /*
* 对红黑树的节点(y)进行右旋转
*
* 右旋示意图(对节点y进行左旋):
* py py
* / /
* y x
* / \ --(右旋)--> / \ #
* x ry lx y
* / \ / \ #
* lx rx rx ry
*
*/
template<typename Key, typename Value>
inline void RedBlackTree<Key, Value>::rotateRight(Node * x)
{
Node *x = y->left;
y->left = x->right;
if (x->right != nullptr)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == nullptr)
root = x;
else {
if (y == y->parent->right)
y->parent->right = x;
else
y->parent->left = x;
}
x->right = y;
y->parent = x;
} template<typename Key, typename Value>
inline typename RedBlackTree<Key, Value>::Node * RedBlackTree<Key, Value>::deleteMin(Node * head)
{
if (head == nullptr)
return nullptr;
Node *node = head;
Node *lastNode = nullptr;
while (node->left != nullptr)
{
lastNode = node;
node = node->left;
}
lastNode->left = node->right;
if (node->right != nullptr)
node->right->parent = lastNode;
return head;
} template<typename Key, typename Value>
inline typename RedBlackTree<Key, Value>::Node * RedBlackTree<Key, Value>::min(Node * head)
{
if (head == nullptr)
return nullptr;
Node *node = head;
while (node->left != nullptr)
node = node->left;
return node;
} template<typename Key, typename Value>
inline void RedBlackTree<Key, Value>::insert(Key key, Value value)
{
Node *parent = nullptr;
Node **ppNode = &root;
while (*ppNode != nullptr)
{
parent = *ppNode;
if (key < (*ppNode)->key)
ppNode = &((*ppNode)->left);
else
ppNode = &((*ppNode)->right);
}
if (*ppNode == nullptr) {
*ppNode = new Node(key, value, RED);
(*ppNode)->parent = parent;
} // 结点是根
if (parent == nullptr) {
root->color = Node::BLACK;
return;
} Node *node = *ppNode;
// 调整
while (node->parent->color == Node::RED)
{
Node *parent = node->parent;
Node *gparent = node->parent->parent;
if (parent == gparent->left)
{
Node *uncle = gparent->right;
if (uncle->color == RED)
{
parent->color = BLACK;
uncle->color = BLACK;
gparent->color = RED;
node = gparent;
}
else if (uncle->color == BLACK)
{
if (node == parent->right)
{
node = parent;
rotateLeft(node);
}
else
{
parent->color = BLACK;
gparent->color = RED;
rotateRight(gparent);
}
}
}
else if (parent == gparent->right)
{
Node *uncle = gparent->left;
if (uncle->color == RED)
{
parent->color = BLACK;
uncle->color = BLACK;
gparent->color = RED;
node = gparent;
}
else if (uncle->color == BLACK)
{
if (node == parent->left)
{
node = parent;
rotateRight(node);
}
else
{
parent->color = BLACK;
gparent->color = RED;
rotateLeft(gparent);
}
}
}
}
} template<typename Key, typename Value>
inline void RedBlackTree<Key, Value>::erase(Key key)
{
Node *lastNode = nullptr;
Node *node = root;
while (node != nullptr)
{
if (key < node->key) {
lastNode = node;
node = node->left;
}
else if (key > node->key) {
lastNode = node;
node = node->right;
}
else {
Node **plastNode = nullptr;
// 注意树根
if (lastNode == nullptr)
plastNode = &root;
else
plastNode = &lastNode;
// 无节点的情况
if (node->left == nullptr && node->right == nullptr)
{
if ((*plastNode)->left == node)
{
(*plastNode)->left = nullptr;
delete node;
}
else if ((*plastNode)->right == node)
{
(*plastNode)->right = nullptr;
delete node;
}
}
// 两个节点的情况
else if (node->left != nullptr && node->right != nullptr) {
Node *star = min(node->right);
star->right = deleteMin(node->right);
if (star->right != nullptr)
star->right->parent = star;
star->left = node->left;
if (star->left != nullptr)
star->left->parent = star;
delete node;
}
// 只有一个节点的情况
else if (node->left == nullptr) {
if ((*plastNode)->left == node) {
(*plastNode)->left = node->right;
if (node->right != nullptr)
node->right->parent = *plastNode;
delete node;
}
else if ((*plastNode)->right == node) {
(*plastNode)->right = node->right;
if (node->right != nullptr)
node->right->parent = *plastNode;
delete node;
}
}
else if (node->right == nullptr) {
if ((*plastNode)->right == node) {
(*plastNode)->right = node->left;
if (node->left != nullptr)
node->left->parent = *plastNode;
delete node;
}
else if ((*plastNode)->left == node) {
(*plastNode)->left = node->left;
if (node->left != nullptr)
node->left->parent = *plastNode;
delete node;
}
} }
} while (node != root && node->color == BLACK)
{
if (node == node->parent->left)
{
Node* brother = node->parent->right;
if (brother->color == RED)
{
brother->color = BLACK;
node->parent->color = RED;
rotateLeft(node->parent);
}
else
{
if (brother->left->color == BLACK && brother->right->color == BLACK)
{
brother->color = RED;
node = node->parent;
}
else if (brother->right->color == BLACK)
{
brother->color = RED;
brother->left->color = BLACK;
RotateRight(brother);
}
else if (brother->right->color == RED)
{
brother->color = node->parent->color;
node->parent->color = BLACK;
brother->right->color = BLACK;
rotateLeft(node->parent);
node = root;
}
}
}
else
{
Node* brother = node->parent->left;
if (brother->color == RED)
{
brother->color = BLACK;
node->parent->color = RED;
rotateRight(node->parent);
}
else
{
if (brother->left->color == BLACK && brother->right->color == BLACK)
{
brother->color = RED;
node = node->parent;
}
else if (brother->left->color == BLACK)
{
brother->color = RED;
brother->right->color = BLACK;
rotateLeft(brother);
}
else if (brother->left->color == RED)
{
brother->color = node->parent->color;
node->parent->color = BLACK;
brother->left->color = BLACK;
rotateRight(node->parent);
node = root;
}
}
}
}
node->parent = root; //最后将node置为根结点,
node->color = BLACK; //并改为黑色。
}
} #endif /*__RED_BLACK_TREE_H__*/

红黑树 C++实现的更多相关文章

  1. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  2. jdk源码分析红黑树——插入篇

    红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...

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

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

  4. 定时器管理:nginx的红黑树和libevent的堆

    libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到ac ...

  5. 从2-3-4树到红黑树(下) Java与C的实现

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处   http://www.cnblogs.com/nullzx/ 相关博客: 从2-3-4树到红黑树(上) 从2-3-4树到红黑树(中) 1. 实现技 ...

  6. 红黑树/B+树/AVL树

    RB Tree 红黑树  :http://blog.csdn.net/very_2/article/details/5722682 Nginx的RBTree实现   :http://blog.csdn ...

  7. 论AVL树与红黑树

    首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...

  8. DataStructure——红黑树学习笔记

    1.前言 本文伪码和解释参考: http://blog.csdn.net/v_JULY_v/article/details/6105630 C实现的源码本文未贴出,请见: http://blog.cs ...

  9. 红黑树(Red-Black tree)

    红黑树又称红-黑二叉树,它首先是一颗二叉树,它具体二叉树所有的特性.同时红黑树更是一颗自平衡的排序二叉树.我们知道一颗基本的二叉树他们都需要满足一个基本性质–即树中的任何节点的值大于它的左子节点,且小 ...

  10. map,hash_map, hash_table, 红黑树 的原理和使用

    在刷算法题的时候总是碰到好多题,号称可以用hash table来解题.然后就蒙圈了. 1.首先,map和hash_map的区别和使用: (1)map底层用红黑树实现,hash_map底层用hash_t ...

随机推荐

  1. 基于回调的事件处理——重写onTouchEvent方法响应触摸屏事件

    对于Android提供的事件处理模型,不难发现基于监听的事件处理模型具有更大的优势: 基于监听的事件模型分工更加明确,事件源.事件监听有两个类分开实现,因此具有更好的维护性. Android的事件处理 ...

  2. SSH系统介绍

    SSH的系统中,对象的调用流程是:JSP->Action->Service->DAO->Hibernate,数据的流向是ActionFormBean接受用户的数据,Action ...

  3. spring mvc 入门示例

    classpath <?xml version="1.0" encoding="UTF-8"?> <classpath> <cla ...

  4. doubango(5)--SIP协议栈传输层的启动

    SIP协议的INVITE消息发起流程 当通过sip协议发起一个会话时,需要通过invite消息实现该流程.而SIP协议是一个基于事务的协议,每一个sip会话的都是通过sip部件间的一系列消息来完成的. ...

  5. 车大棒浅谈for循环+canvas实现黑客帝国矩形阵

    背景: 一日在网上闲逛的之时,突然看到一个利用JQ插件实现canvas实现的电影黑客帝国的小Demo.觉得创意不错,就下载下来研究一下. 网上浏览jQuery的写法 $(document).ready ...

  6. Bootstrap入门(十六)组件10:well和具有响应式特性的嵌入内容

    Bootstrap入门(十六)组件10:well和具有响应式特性的嵌入内容 well组件可以为内容增添一种切入效果. 具有响应式特性的嵌入内容可以根据被嵌入内容的外部容器的宽度,自动创建一个固定的比例 ...

  7. 修改/home内子目录的名字

    每次装Linux系统我都会直接安装英文版,虽然中文版方便使用,但是在终端里面会有诸多不便,例如/home目录里面那些子文件夹就是一个很大的麻烦了,不过如果你安装了中文版的系统,还是有办法改成英文的. ...

  8. 为什么python适合写爬虫?(python到底有啥好的?!)

    我用c#,java都写过爬虫.区别不大,原理就是利用好正则表达式.只不过是平台问题.后来了解到很多爬虫都是用python写的.因为目前对python并不熟,所以也不知道这是为什么.百度了下结果: 1) ...

  9. Git学习之路(2)-安装GIt和创建版本库

    ▓▓▓▓▓▓ 大致介绍 前面一片博客介绍了Git到底是什么东西,如果有不明白的可以移步 Git学习之路(1)-Git简介 ,这篇博客主要讲解在Windows上安装Git和创建一个版本库 ▓▓▓▓▓▓ ...

  10. Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析

    转载请注明出处:CN_Simo. 题解: 本篇内容主讲Qt应用从创建到发布的整个过程,旨在帮助读者能够快速走进Qt的世界. 本来计划是讲解Qt源码静态编译,如此的话读者可能并不能清楚地知道为何要静态编 ...