C++实现红黑树,仿STL封装
//RB_Tree.hpp
//The code of red black trees
//2011/12/31 by Adoo
// The foundation :http://www.roading.org/?p=691 #ifndef RB_TREES_HPP
#define RB_TREES_HPP
#include<iterator>
#include<iomanip>
#include<deque>
enum RB_Color{
red,
black
};
template<typename Type>
class RB_Tree{
private:
struct rb_node;
class node_iterator;
public:
typedef node_iterator iterator;
typedef const node_iterator const_iterator; RB_Tree(){
_nil->_color=black;
_root=_nil;
};
~RB_Tree()
{
for(iterator iter=begin(); iter !=end();)
{
eraser(iter++);
}
_root=_nil;
}
iterator begin(){
return sub_min(_root);
}
iterator end(){
return iterator(_nil);
}
static iterator sub_min(iterator iter){
rb_node *min=iter.pointer();
while(min->_left !=_nil)
{
min=min->_left;
}
return min;
}
iterator insert(Type value){
rb_node *y=_nil;
rb_node *z=new rb_node; //create a node by the value
//needn't set the z's color ,because red is rb_node's default color
z->_value=value;
z->_left=_nil;
z->_right=_nil; rb_node* x=_root; //x iterator from _root
while(x !=_nil )
{
y=x;
if(x->_value< z->_value)
x=x->_right;
else
x=x->_left;
}
z->_parent=y;
if(y==_nil) //determine z should be y's left or right
_root=z;
else
if(y->_value < z->_value)
y->_right=z;
else
y->_left=z; rb_insert_fixup(z); //restore the red black properties
return z;
}
iterator eraser(iterator iter){
rb_node* z=iter.pointer();
rb_node* y=z;
RB_Color y_color=y->_color;
rb_node *x=NULL; if(z->_left==_nil ){ //case1: z's left child is nil
x=z->_right;
transplant(z, z->_right);
}
else{
if(z->_right==_nil){// case2: z's right child is nil
x=z->_left;
transplant(z, z->_left);
}
else{//case3: both children of z are not nil
y=sub_min(z->_right).pointer();
y_color=y->_color;
x=y->_right;
if(y->_parent==z)
x->_parent=y;
else{
transplant(y, y->_right);
//link z's right subtree into y, only y isn't z's child;
y->_right=z->_right;
y->_right->_parent=y;
}
transplant(z, y);
//link z's subtree into y.
y->_left=z->_left;
y->_left->_parent=y;
y->_color=z->_color;
}
}
iterator result = ++iterator(z);
delete z;
if(y_color==black)
eraser_fixup(x);
return result;
}; private:
void transplant(rb_node *u, rb_node *v){
if(u->_parent == _nil)
{
_root=v;
}
else
if(u== u->_parent->_left)
u->_parent->_left=v;
else
u->_parent->_right=v;
v->_parent=u->_parent;
};
void left_rotate(rb_node *x){
rb_node* y=x->_right; //set y
x->_right=y->_left; //turn y's left subtree into x's right subtree
if(y->_left !=_nil)
y->_left->_parent=x;
y->_parent=x->_parent; //link y to x's parent
if(x->_parent != _nil )
{
if(x->_parent->_left==x)
x->_parent->_left=y;
else
x->_parent->_right=y;
}
else
_root=y;
y->_left=x; //put x on y's left
x->_parent=y;
}
void right_rotate(rb_node *x)
{
rb_node* y=x->_left; //set y;
x->_left=y->_right; //turn y's right subtree into x's left subtree
if(y->_right != _nil)
y->_right->_parent=x;
y->_parent=x->_parent; //link y to x's parent
if(x->_parent != _nil)
{
if(x==x->_parent->_left)
x->_parent->_left=y;
else
x->_parent->_right=y;
}
else
_root=y;
y->_right=x; //put x on y's right;
x->_parent=y;
}
void rb_insert_fixup(rb_node* z){
while(z->_parent->_color==red){
if(z->_parent==z->_parent->_parent->_left){
rb_node* y=z->_parent->_parent->_right;
if(y->_color==red){
z->_parent->_color=black;
y->_color=black;
z->_parent->_parent->_color=red;
z=z->_parent->_parent;
}
else{
if(z==z->_parent->_right){
z=z->_parent;
left_rotate(z);
}
z->_parent->_color=black;
z->_parent->_parent->_color=red;
right_rotate(z->_parent->_parent);
}
}
else{
rb_node* y=z->_parent->_parent->_left;
if(y->_color==red){
z->_parent->_color=black;
y->_color=black;
z->_parent->_parent->_color=red;
z=z->_parent->_parent;
}
else{
if(z==z->_parent->_left){
z=z->_parent;
right_rotate(z);
}
z->_parent->_color=black;
z->_parent->_parent->_color=red;
left_rotate(z->_parent->_parent);
}
}
}
_root->_color=black;
};;
void eraser_fixup(rb_node* x){
while(x != _root && x->_color ==black){
if(x==x->_parent->_left){
rb_node* w=x->_parent->_right;
if(w->_color == red){ //case 1: x's sbling w is red.
x->_parent->_color=red;
w->_color=black;
left_rotate(x->_parent); //convert case 1 to case 2.
}
else{//case 2 : x's sbling w is black.
if(w->_left->_color == black && w->_right->_color == black){
//case 2.1 : both children of w are black
w->_color=red;
x=x->_parent;
}
else{
if(w->_left->_color==red && w->_right->_color==black){
//case 2.2: w's left child is red and w's right child is black.
//we convert this case to case 2.3.
w->_left->_color=black;
w->_color=red;
right_rotate(w);
w=x->_parent->_right;
}
//case 2.3: w's right child is red;
w->_color=x->_parent->_color;
w->_parent->_color=black;
w->_right->_color= black;
left_rotate(x->_parent);
x=_root; //terminate the loop;
}
}
}
else{
rb_node* w=x->_parent->_right;
if(w->_color == red){
x->_parent->_color=red;
w->_color=black;
left_rotate(x->_parent);
}
else{
if(w->_right->_color == black && w->_left->_color == black){
w->_color=red;
x=x->_parent;
}
else{
if(w->_right->_color==red && w->_left->_color == black){
w->_right->_color=black;
w->_color=red;
left_rotate(w);
w=x->_parent->_left;
}
w->_color=x->_parent->_color;
w->_parent->_color=black;
w->_left->_color= black;
right_rotate(x->_parent);
x=_root; //terminate the loop;
}
}
}
}
x->_color=black;
}; private:
rb_node* _root;
public:
static rb_node* _nil;
}; template<typename Type>
struct RB_Tree<Type>::rb_node
{
Type _value;
rb_node *_left;
rb_node *_right;
rb_node *_parent;
RB_Color _color;
rb_node()
:_value(Type()),_left(NULL),_right(NULL),_parent(NULL),_color(red)
{};
}; template<typename Type>
class RB_Tree<Type>::node_iterator:
public std::iterator<std::bidirectional_iterator_tag ,rb_node>
{
public:
node_iterator(rb_node* n): _node(n){}; Type& operator* () const{
return _node->_value;
}; rb_node* operator ->()const
{
return _node;
}; node_iterator operator++ ()
{
if(_node==RB_Tree<Type>::_nil)
return _node;
if(_node->_right!=RB_Tree<Type>::_nil)
{
*this=RB_Tree<Type>::sub_min(_node->_right);
}
else
{
rb_node *parent=_node->_parent;
while(parent !=RB_Tree<Type>::_nil&& _node==parent->_right)
{
_node=parent;
parent=parent->_parent;
}
_node=parent;
}
return *this;
} node_iterator operator++(int){
node_iterator ret(*this);
++*this;
return ret;
} bool operator ==( node_iterator r_iter)
{
return _node == r_iter._node;
}; bool operator !=( node_iterator r_iter){
return _node != r_iter._node;
} rb_node* pointer()
{
return _node;
}
private:
rb_node* _node;
};
#endif
//各种
C++实现红黑树,仿STL封装的更多相关文章
- stl vector、红黑树、set、multiset、map、multimap、迭代器失效、哈希表(hash_table)、hashset、hashmap、unordered_map、list
stl:即标准模板库,该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法 六大组件: 容器.迭代器.算法.仿函数.空间配置器.迭代适配器 迭代器:迭代器(iterator)是一种抽象的设计 ...
- stl map底层之红黑树插入步骤详解与代码实现
转载注明出处:http://blog.csdn.net/mxway/article/details/29216199 本篇文章并没有详细的讲解红黑树各方面的知识,只是以图形的方式对红黑树插入节点需要进 ...
- [转]SGI STL 红黑树(Red-Black Tree)源代码分析
STL提供了许多好用的数据结构与算法,使我们不必为做许许多多的重复劳动.STL里实现了一个树结构-Red-Black Tree,它也是STL里唯一实现的一个树状数据结构,并且它是map, multim ...
- SGI STL红黑树中迭代器的边界值分析
前言 一段程序最容易出错的就是在判断或者是情况分类的边界地方,所以,应该对于许多判断或者是情况分类的边界要格外的注意.下面,就分析下STL中红黑树的迭代器的各种边界情况.(注意:分析中STL使用的版本 ...
- 【stl学习笔记】红黑树
转自维基百科 红黑树是一种平衡二叉搜索树,它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目. 性质: 红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色.在二叉查找 ...
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之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 ...
- 论AVL树与红黑树
首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...
- map,hash_map, hash_table, 红黑树 的原理和使用
在刷算法题的时候总是碰到好多题,号称可以用hash table来解题.然后就蒙圈了. 1.首先,map和hash_map的区别和使用: (1)map底层用红黑树实现,hash_map底层用hash_t ...
随机推荐
- [置顶] AFNetworking 2.0 新特性讲解之AFHTTPSessionManager
AFNetworking 2.0 相比1.0 API 接口改动还是很大的. 其中一个便是 AFURLSessionManager,当然如果你不太熟悉,或者为了兼容低版本,你依然可以选择AFHTTPRe ...
- Android RecyclerView使用(一)
RecyclerView一种可以替换掉listview gridview 瀑布流等控件的新视图控件,控制视图回收和复用 ==优化内存可以替换listview 与listview的不同之处是:listv ...
- Android开源项目分类汇总【畜生级别】[转]
Android开源项目分类汇总 欢迎大家推荐好的Android开源项目,可直接Commit或在 收集&提交页 中告诉我,欢迎Star.Fork :) 微博:Trinea 主页:www.t ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(44)-工作流设计-设计表单
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(44)-工作流设计-设计表单 系列目录 设计表单是比较复杂的一步,完成一个表单的设计其实很漫长,主要分为四 ...
- Raspberry Pi + 3个USB摄像头 + Motion(简易监控设备配置记录1——介绍以及安装) 分类: Raspberry Pi 服务器搭建 2015-04-12 19:21 226人阅读 评论(0) 收藏
参考: Debian官网链接 Motion官网链接 首先,参见Debian官网链接对Motion的介绍,网页中包含了所有相关依赖包,请首先确保这些依赖包的安装. Motion介绍 摘出对Motion的 ...
- gitlab一键安装
参考 https://about.gitlab.com/downloads/
- UVa 993: Product of digits
这道题很简单.先将N用2,3,5,7(即10以内的素数)分解因数(需要先特殊判断N不为1),然后将可以合并的因数合并(如2*2合并成4,)这样求得的结果位数会减少,大小肯定会小一些.具体实现见代码. ...
- Cocos2d-x游戏开发中的消息机制:CCNotificationCenter的使用
在HTML5游戏开发中,js可以使用Event对象的addEventListener(添加事件监听).dispatchEvent(触发事件)实现监听机制,如果在coocos2d-x中,去实现这种机制该 ...
- [转] Mac OX上安装MongoDb
https://scotch.io/tutorials/an-introduction-to-mongodb MongoDB的安装有好多种安装方法,有普通青年的HomeBrew方式,也有文艺青年的源码 ...
- iOS 使用Charts框架 折线,柱状,K线,饼状,雷达全攻略
我是前言: 大约几个月前我在某平台写了一篇文章, 文中简单地介绍了Charts两种图表的样式的使用, 不过有种意犹未尽的感觉, 利用周末的空闲时间再次看了看, 有了新的收获, 今天发出来,分享给大家, ...