平衡树之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 ...
随机推荐
- 中断API之enable_irq
void enable_irq(unsigned int irq) 用于使能一个irq. void disable_irq(unsigned int irq)则用于禁止一个irq 其使用的例程如下: ...
- 【Codeforces Round #421 (Div. 2) B】Mister B and Angle in Polygon
[题目链接]:http://codeforces.com/contest/820/problem/B [题意] 给你一个正n边形; 然后让你在这正n边行中选3个点,组成一个角; 找出角的大小和所给的角 ...
- [Recompose] Refactor React Render Props to Streaming Props with RxJS and Recompose
This lesson takes the concept of render props and migrates it over to streaming props by keeping the ...
- Android怎样从外部跳进App
解决问题有两个作用: 1.不用打开App直接进入某页面 2.实现App分享到外部,同一时候由外部进入App的闭环. 这个话题能够分双方面来讲.一方面是从微信进入App,还有一方面是从网页进入App. ...
- 赵雅智_运用Bitmap和Canvas实现图片显示,缩小,旋转,水印
上一篇已经介绍了Android种Bitmap和Canvas的使用,以下我们来写一个详细实例 http://blog.csdn.net/zhaoyazhi2129/article/details/321 ...
- PipeCAD之管道标准库PipeStd(2)
PipeCAD之管道标准库PipeStd(2) eryar@163.com Key Words. PipeCAD, PipeStd, 管道设计软件,管件库 1. Introduction 管道标准部件 ...
- 在Mac OS X上安装使用lazarus 1.6.4
一直觉得delphi的OO做得比C++还完善, 但如今日落西真是让人感到唏嘘, 这并不意味着delphi比C++差, 它的创始人被微软挖墙脚后创造了C#系列开发工具, 设计理念大部分与Delphi相 ...
- 动态代理(jdk--cglib)
JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类 ...
- jython awt demo
jython awt demo : """\ Create a panel showing all of the colors defined in the pawt.c ...
- 联想 Thinkserver TS250服务器RAID1 重建测试
1.RAID1状态下,拨掉其中一块硬盘后,RAID1即失效. 2.重新插入后,在进行系统后会自动重建 *RAID1 提示Rebuild *进入桌面后软件,显示重建进度 软件下载地址:https://p ...