平衡树之RB-tree
#include <memory> template<class T>
struct rb_node
{
T key;
bool color;//true red | false black
std::shared_ptr<rb_node> lchild, rchild, parent; rb_node(T key, bool color = true, std::shared_ptr<rb_node> lchild = nullptr,
std::shared_ptr<rb_node> rchild = nullptr, std::shared_ptr<rb_node> parent = nullptr)
:key(key)//此处不能使用this:现在对象还没被构建起来
{
//赋值,初始化在初始化列表中执行
this->color = color;
this->lchild = lchild;
this->rchild = rchild;
this->parent = parent;
}
}; template<class T>
class rb_tree
{
private:
std::shared_ptr<rb_node<T>> root;
std::shared_ptr<rb_node<T>> nil;//叶节点
void left_rotation(std::shared_ptr<rb_node<T>> a)
{
if (a == nullptr) return;
std::shared_ptr<rb_node<T>> b = a->rchild;
if (b == nullptr) return;
if (b->lchild != nullptr)
b->lchild->parent = a;
a->rchild = b->lchild; if (a->parent == nil)
root = b;//rbtree的root以nil为父节点
else
{
if (a->parent->lchild == a)
a->parent->lchild = b;
else
a->parent->rchild = b;
}
b->parent = a->parent; b->lchild = a;
a->parent = b;
}
void right_rotation(std::shared_ptr<rb_node<T>> a)
{
if (a == nullptr) return;
std::shared_ptr<rb_node<T>> b = a->lchild;
if (b == nullptr) return;
if (b->rchild != nullptr)
b->rchild->parent = a;
a->lchild = b->rchild; if (a->parent == nil)
root = b;
else
{
if (a->parent->lchild == a)
a->parent->lchild = b;
else
a->parent->rchild = b;
}
b->parent = a->parent; b->rchild = a;
a->parent = b;
} public:
rb_tree()
{
root = nullptr;
T key;
nil = std::make_shared<rb_node<T>>(key, false);
}
void insert(T key)
{
std::shared_ptr<rb_node<T>> tmp = std::make_shared<rb_node<T>>(key, true, nil, nil, nil);
std::shared_ptr<rb_node<T>> ptr = root; //情况1:树为空
if (ptr == nullptr)
{
tmp->color = false;
root = tmp;
return;
}
while (true)
{
if (key <= ptr->key)
{
if (ptr->lchild == nil) break;
ptr = ptr->lchild;
}
else
{
if (ptr->rchild == nil) break;
ptr = ptr->rchild;
}
} if (key <= ptr->key)
ptr->lchild = tmp;
else
ptr->rchild = tmp;
tmp->parent = ptr; while(true)
{
if (ptr == nil)//注意root可能被情况三修改为red,记得加特判
{
tmp->color = false;
root = tmp;
return;
} //情况2:插入节点的父节点为黑色
if (!ptr->color) return; /*情况3:插入节点的父节点和叔节点都存在且都为红色*/
if (ptr->parent->lchild->color && ptr->parent->rchild->color)
{
ptr->parent->color = true;
ptr->parent->lchild->color = false;
ptr->parent->rchild->color = false; tmp = ptr->parent;
ptr = tmp->parent;
continue;
}
if (ptr->parent->lchild == ptr)
{
//情况4:右旋
if (tmp == ptr->lchild)
{
ptr->parent->color = true;
ptr->color = false;
right_rotation(ptr->parent);
return;
}
else
{
//情况5:左旋 + 右旋
left_rotation(ptr);
tmp = ptr;
ptr = tmp->parent;
continue;
}
}
else
{
//情况4:左旋
if (tmp == ptr->rchild)
{
ptr->parent->color = true;
ptr->color = false;
left_rotation(ptr->parent);
return;
}
else
{
//情况5:右旋+左旋
right_rotation(ptr);
tmp = ptr;
ptr = tmp->parent;
continue;
}
}
}
}
void earse(T key)
{
//待续
}
};
平衡树之RB-tree的更多相关文章
- 红黑树(R-B Tree)
R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). ...
- R-B Tree
1.简介 R-B Tree,全称Red-Black Tree,又称为"红黑树",为一种自平衡二叉查找树(特殊的平衡二叉树,都是在插入和删除操作时通过特定操作保持二叉树的平衡,从而获 ...
- bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2202 Solved: 1226[Submit][Sta ...
- 3224: Tyvj 1728 普通平衡树(finger tree)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 19122 Solved: 8359[Submit][St ...
- 重学数据结构系列之——平衡树之SB Tree(Size Blanced Tree)
学习来源:计蒜客 平衡树 1.定义 对于每一个结点.左右两个子树的高度差的绝对值不超过1,或者叫深度差不超过1 为什么会出现这样一种树呢? 假如我们依照1-n的顺序插入到二叉排序树中,那么二叉排序树就 ...
- 红黑树(RB Tree)
看到一篇很好的文章 文章来源:http://www.360doc.com/content/15/0730/00/14359545_488262776.shtml 红黑树是一种高效的索引树,多于用关联数 ...
- java数据结构——红黑树(R-B Tree)
红黑树相比平衡二叉树(AVL)是一种弱平衡树,且具有以下特性: 1.每个节点非红即黑; 2.根节点是黑的; 3.每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的; 4.如图所示,如果一个 ...
- 树-红黑树(R-B Tree)
红黑树概念 特殊的二叉查找树,每个节点上都有存储位表示节点的颜色是红(Red)或黑(Black).时间复杂度是O(lgn),效率高. 特性: (1)每个节点或者是黑色,或者是红色. (2)根节点是黑色 ...
- 关于红黑树(R-B tree)原理,看这篇如何
学过数据数据结构都知道二叉树的概念,而又有多种比较常见的二叉树类型,比如完全二叉树.满二叉树.二叉搜索树.均衡二叉树.完美二叉树等:今天我们要说的红黑树就是就是一颗非严格均衡的二叉树,均衡二叉树又是在 ...
- [转]SGI STL 红黑树(Red-Black Tree)源代码分析
STL提供了许多好用的数据结构与算法,使我们不必为做许许多多的重复劳动.STL里实现了一个树结构-Red-Black Tree,它也是STL里唯一实现的一个树状数据结构,并且它是map, multim ...
随机推荐
- websocket调试工具
http://www.blue-zero.com/WebSocket/ wss://yy.xxx.com/video/websocket/client.ws
- HDU 4906 Our happy ending
题意: Given a sequence a_1,a_2,...,a_n, if we can take some of them(each a_i can only be used once), a ...
- 题解 P2504 【[HAOI2006]聪明的猴子】
这道题要坑死人啊... 第一次做40分,其他RE,改了一次之后就变成20分了... 究其原因,是有一个数组(dis)开的太小了,于是最后本蒟蒻就随手开了个五百万,然后,就AC了. 看到有一篇题解说求距 ...
- Java基础学习总结(16)——Java制作证书的工具keytool用法总结
一.keytool的概念 keytool 是个密钥和证书管理工具.它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务.在 ...
- Chrome无界面浏览模式与自定义插件加载问题
环境:Python 3.5.x + Selenium 3.4.3 + Chromedriver 2.30 + Chrome 60 beta或Chromium Canary 61 + WIN10 Chr ...
- C#+ArcGIS Engine 获取地图中选中的要素
转自 C#+ArcGIS Engine 获取地图中选中的要素 C#+ArcGIS Engine 获取地图中选中的要素 提供一种简单遍历获取地图中选中要素的方法,代码如下: List<IFeatu ...
- Equals和==比較
总结一下: 对于字符串来说.两个比較的都是对象的值,而且是等效的,这是由于MS重写了==运算符和Equals方法所致 对于非字符串的其它引用类型(非匿名类型)两个比較的都是对象 ...
- SICP 习题 (2.11)解题总结:区间乘法的优化
SICP 习题 2.11又出现Ben这个人了,如曾经说到的,仅仅要是Ben说的一般都是对的. 来看看Ben说什么.他说:"通过监測区间的端点,有可能将mul-interval分解为9中情况, ...
- Python使用Redis实现一个简单作业调度系统
Python使用Redis实现一个简单作业调度系统 概述 Redis作为内存数据库的一个典型代表,已经在非常多应用场景中被使用,这里仅就Redis的pub/sub功能来说说如何通过此功能来实现一个简单 ...
- web前端开发——AJAX入门
什么是AJAX AJAX: A New Approach to Web Applications XML AJAX是老技术新思想. 它所包括的内容我们之前都接触过.例如以下: (1)使用XHTML和C ...