stl源码剖析 详细学习笔记 RB_tree (1)
//
// RB_tree_STL.cpp
// 笔记
//
// Created by fam on 15/3/21.
//
//
#include "RB_tree_STL.h"
//---------------------------15/03/21----------------------------
RB_tree
{
/*
一个由上而下程序:
为了避免父子节点皆为红色的情况持续向上层发展,形成处理时效上的瓶颈,可以从上向下处理,
假设新增的节点为a,那就沿着a的路径,只要看到一个节点的两个子节点都是红色,就把这个节点改为红色
其他两个子节点改成黑色。
*/
//RB_tree的节点设计
typedef
bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red =
const __rb_tree_color_type __rb_tree_black =
true;
//__rb_tree_node_base
struct __rb_tree_node_base
{
typedef __rb_tree_color_type color_type;
typedef __rb_tree_node_base* base_ptr;
color_type color;
base_ptr parent;
base_ptr left;
base_ptr right;
//一直向左走,就会找到最小值
static base_ptr minimum(base_ptr x)
{
while (x->left !=
)
x=x->left;
return x;
}
//一直向右走
static base_ptr maximum(base_ptr x)
{
while (x->right !=
)
x=x->right;
return x;
}
};
//__rb_tree_node
template<class Value>
struct __rb_tree_node :
public __rb_tree_node_base
{
typedef __rb_tree_node<Value>* link_type;
Value value_field;
};
//节点设计结束
/*
re_tree的迭代器
re_tree的迭代器和slist的迭代器很相似,都是分成两层结构
re_tree属于双向迭代器,但是不具备随机定位的能力
*/
//__rb_tree_base_iterator
struct __rb_tree_base_iterator
{
typedef __rb_tree_node_base::base_ptr base_ptr;
typedef bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
base_ptr node;
void increment()
{
if(node->right !=
)
{
node = node->right;
while (node->left !=
)
node =node->left;
}
//只要node是他父节点的右儿子,他就比他父亲大,我们要找比node大的
else
{
base_ptr y= node->parent;
while(node == y->right)
{
node = y;
y = y->parent;
}
if(node->right != y)//如果node是根节点,而且没有右儿子
node=y;
}
}
void decrement()
{
//这个发生在node时header或者end()时
if(node->color == __rb_tree_red &&
node->parent->parent == node)
node =node->right;
else
)
{
base_ptr y = node->left;
while(y->right !=
)
y = y->right;
node = y;
}
else
{
base_ptr y =node->parent;
while(node == y->left)
{
node = y;
y = y->parent;
}
node = y;
}
}
//原文说increment有4种状况,其实只有三种,状况2并不是一种结果
};
template<class Value,class Ref,class
Ptr>
struct __rb_tree_iterator :
public __rb_tree_base_iterator
{
typedef Value value_type;
typedef Ref reference;
typedef Ptr pointer;
typedef __rb_tree_iterator<Value, Value&, Value*> iterator;
typedef __rb_tree_iterator<Value,const Value&,const Value*> const_iterator;
typedef __rb_tree_iterator<Value, Ref, Ptr> self;
//经过多日的stl熏陶,感觉有些明白self和iterator的关系了,self是当前的节点本身(因为self用到的地方
//很多,可以简化书写,iterator是一个类型属性供别人使用的。
typedef __rb_tree_node<Value>* link_type;
//构造函数
__rb_tree_iterator(){}
__rb_tree_iterator(link_type x) {node = x;}
__rb_tree_iterator(const iterator& x) {node = it.node;}
referenceoperator*()
const {return link_type(node)->value_field;}
#ifdef __SGI_STL_NO_ARROW_OPERATOR
pointeroperator->()
const {return &(operator*());}
#endif
//++ --操作
self&operator++() {increment();
return *this;}
self&operator++(){increment();return *this;}
selfoperator++(int)
{
self tmp = *this;
increment();
return tmp;
}
self&operator--(){decrement();return *this;}
selfoperator--(int)
{
self tmp = *this;
decrement();
return tmp;
}
}
//class rb_tree
template<class Key,class Value,
class KeyOfValue,class Compare,
class Alloc = alloc>
class rb_tree
{
protected:
typedef
void* void_point;
typedef __rb_tree_node_base* base_ptr;
typedef __rb_tree_node<Value> rb_tree_node;
typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator;
typedef __rb_tree_color_type color_type;
public:
typedef Key key_type;
typedef Value value_type;
typedef value_type* pointer;
typedef
const value_type* const_pointer;
typedef value_type& reference;
typedef
const value_type& const_reference;
typedef rb_tree_node* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
//内存分配和释放
link_type get_node()
{
return rb_tree_node_allocator::allocate();
}
void put_node(link_type p)
{
rb_tree_node_allocator::deallocate(p);
}
//申请内存并调用构造函数等于new操作
link_type create_node(const value_type& x)
{
link_type tmp = get_node();
__STL_TRY
{
construct(&tmp->value_field,x);
}
__STL_UNWIND(put_node(tmp));
return tmp;
}
//克隆一个节点,只有颜色和键值,不会拷贝关系(左右儿子) 有个疑问,为什么parent没有赋0
link_type clone_node(link_type x)
{
link_type tmp = create_node(x->value_field);
tmp->color = x->color;
tmp->left =;
tmp->right =;
return temp;
}
void destroy_node(link_type p)
{
destroy(&p->value_field);
put_node(p);
}
protected:
size_type node_count;
link_type header;
Compare key_compare;
link_type& root()const {return (link_type&) header->parent;}
link_type& leftmost()const {return (link_type&) header->left;}
link_type rightmost()const {return (link_type&) header->right;}
//一下12个函数全部为了简化取成员操作
static link_type& left(link_type x)
{
return (link_type&)(x->left);
}
static link_type& right(link_type x)
{
return (link_type&)(x->right);
}
static link_type& parent(link_type x)
{
return (link_type&)(x->parent);
}
static reference& value(link_type x)
{
return x->value_field;
}
static
const Key& key(link_type x)
{
return KeyOfValue()( value(x));
}
static color_type& color(link_type x)
{
return (color_type&)(x->color);
}
static link_type& left(base_ptr x)
{
return (link_type&)(x->left);
}
static link_type& right(base_ptr x)
{
return (link_type&)(x->right);
}
static link_type& parent(base_ptr x)
{
return (link_type&)(x->parent);
}
static reference& value(base_ptr x)
{
return ((link_type)x)->value_field;
}
static
const Key& key(base_ptr x)
{
return KeyOfValue()( value(link_type(x)));
}
static color_type& color(base_ptr x)
{
return (color_type&)(link_type(x)->color);
}
//求最大和最小值
static link_type minimum(link_type x)
{
return (link_type) __rb_tree_node_base::minimum(x);
}
static link_type maximum(link_type x)
{
return (link_type) __rb_tree_node_base::maximum(x);
}
public:
typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
private:
iterator __insert(base_ptr x, base_ptr y,const value_type& v);
link_type __copy(link_type x, link_type p);
void __erase(link_type x);
//初始化,给header申请一个节点的内存,让root(header->parent)为0,让左右最值都为header,并设置成红色
void init()
{
header = get_node();
color(header) = __rb_tree_red;
root() =;
leftmost() = header;
rightmost() =header;
}
public:
rb_tree(const Compare& comp=Compare()
: node_count(), key_compare(comp))
{
init();
}
~rb_tree()
{
clear();
put_node(header);
}
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>&
operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x);
public:
//各种基础操作
Compare key_comp()const {return key_compare;}
iterator begin() {return leftmost();}
iterator end() {return header;}
bool empty()
;}
size_type size()const {return node_count;}
size_type max_size());}
public:
pair<iterator,bool> insert_unique(const value_type& x);
};
stl源码剖析 详细学习笔记 RB_tree (1)的更多相关文章
- stl源码剖析 详细学习笔记 RB_tree (2)
//---------------------------15/03/22---------------------------- //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多 ...
- stl源码剖析 详细学习笔记 set map
// // set map.cpp // 笔记 // // Created by fam on 15/3/23. // // //---------------------------15/03 ...
- stl源码剖析 详细学习笔记 hashtable
//---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...
- stl源码剖析 详细学习笔记heap
// // heap.cpp // 笔记 // // Created by fam on 15/3/15. // // //---------------------------15/03/15 ...
- stl源码剖析 详细学习笔记 空间配置器
//---------------------------15/04/05---------------------------- /* 空间配置器概述: 1:new操作包含两个阶段操作 1>调 ...
- stl源码剖析 详细学习笔记 算法(1)
//---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...
- stl源码剖析 详细学习笔记 算法总览
//****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...
- stl源码剖析 详细学习笔记 hashset hashmap
//---------------------------15/03/26---------------------------- //hash_set { /* hash_set概述: 1:这是一个 ...
- stl源码剖析 详细学习笔记priority_queue slist
// // priority_queue.cpp // 笔记 // // Created by fam on 15/3/16. // // //------------------------- ...
随机推荐
- C#安全加密类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.S ...
- SQL Server 请求失败或服务未及时响应。有关详细信息,请参见事件日志或其它适合的错误日志
在打开数据库的时候,突然出现异常错误,然后我去关闭sql server 服务,然后重启服务的时候,不能重启,出现以下错误 “请求失败或服务未及时响应.有关详细信息,请参见事件日志或其它适合的错误日志” ...
- RecyclerView使用技巧(item动画及嵌套高度适配解决方案)
原文地址 · Frank-Zhu http://frank-zhu.github.io/android/2015/02/26/android-recyclerview-part-3/?utm_sou ...
- Redis缓存穿透、缓存雪崩、redis并发问题分析
把redis作为缓存使用已经是司空见惯,但是使用redis后也可能会碰到一系列的问题,尤其是数据量很大的时候,经典的几个问题如下: (一)缓存和数据库间数据一致性问题分布式环境下(单机就不用说了)非常 ...
- Go语言学习笔记(六)net & net/http
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 net import "net" net包提供了可移植的网络I/O接口,包括TCP/IP.UD ...
- Asp.net core 2.0.1 Razor 的使用学习笔记(二)
ASP.net core 2.0.1 中 asp.net identity 2.0.1 的基本使用(一)—启用用户管理 一.修改和启用默认的用户账户管理和角色管理 在Data目录中添加Applicat ...
- jsencrypt加密
在登录时,前台页面的用户名.密码都是明文传输到后台的,漏洞扫描认为这样子不安全,就想到了前台js加密,后台解密的方法,要用到jsencrypt.js,具体代码如下: 前台页面: <!DOCTYP ...
- C语言实现输出杨辉三角
1.倒推法实现输出杨辉三角右半部分,代码如下: #include<stdio.h> int main() { ]; printf("请输入行数n:"); scanf(& ...
- 【Android自动化】unittest测试框架关于用例执行的几种方法
# -*- coding:utf-8 -*- import unittest class test(unittest.TestCase): def setUp(self): print 'This i ...
- window与Linux之间的文件传输
使用工具:WinSCP WinSCP可以直接通过SSH链接你的linux服务器:然后进行文件的复制操作:并且可以直接编辑文件. 1.下载WinSCP 2.登录WinSCP,输入你的Linux 的IP地 ...