深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx

上传人:b****4 文档编号:18449167 上传时间:2022-12-16 格式:DOCX 页数:30 大小:599.30KB
下载 相关 举报
深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx_第1页
第1页 / 共30页
深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx_第2页
第2页 / 共30页
深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx_第3页
第3页 / 共30页
深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx_第4页
第4页 / 共30页
深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx

《深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx(30页珍藏版)》请在冰豆网上搜索。

深入理解STL之RBTree重点讲义资料Word文档下载推荐.docx

因本人能力有限可能无法将红黑树讲得很清楚全面,而且STL红黑树的实现也较为复杂,建议先到下面推荐的几篇博客里去补补知识

∙教你初步了解红黑树

∙【数据结构和算法05】红-黑树(看完包懂~)

∙一步一图一代码,一定要让你真正彻底明白红黑树

红黑树的节点结构

红黑树的节点在二叉树的节点结构上增加了颜色属性,而且,为了更好的进行插入和删除操作,进而增加了指向父节点的指针。

为了更好的弹性,STL红黑树的节点采用双层设计,将不依赖模板的参数提取出来,作为base结构,然后用带模板的节点结构取继承它。

下面是红黑树节点结构的源码:

typedefbool__rb_tree_color_type;

const__rb_tree_color_type__rb_tree_red=false;

//紅色為0

const__rb_tree_color_type__rb_tree_black=true;

//黑色為1

struct__rb_tree_node_base

{

typedef__rb_tree_color_typecolor_type;

typedef__rb_tree_node_base*base_ptr;

color_typecolor;

//节点颜色

base_ptrparent;

//指向父节点

base_ptrleft;

//指向左子节点

base_ptrright;

//指向右子节点

//一直往左走,就能找到红黑树的最小值节点

//二叉搜索树的性质

staticbase_ptrminimum(base_ptrx)

{

while(x->

left!

=0)x=x->

left;

returnx;

}

//一直往右走,就能找到红黑树的最大值节点

staticbase_ptrmaximum(base_ptrx)

right!

right;

};

//真正的节点定义,采用双层节点结构

//基类中不包含模板参数

template<

classValue>

struct__rb_tree_node:

public__rb_tree_node_base

typedef__rb_tree_node<

Value>

*link_type;

Valuevalue_field;

//節點實值

红黑树的迭代器

为了将RBtree实现为一个泛型容器,迭代器的设计很关键。

我们要考虑它的型别,以及前进(increment)、后退(devrement)、提领(dereference)和成员访问(memberaccess)等操作。

迭代器和节点一样,采用双层设计,STL红黑树的节点__rb_tree_node继承于__rb_tree_node_base;

STL的迭代器结构__rb_tree_iterator继承于__rb_tree_base_iterator,我们可以用一张图来解释这样的设计目的。

将这些分开设计,可以保证对节点和迭代器的操作更具有弹性。

下面来看迭代器的源码:

struct__rb_tree_base_iterator

typedef__rb_tree_node_base:

:

base_ptrbase_ptr;

typedefbidirectional_iterator_tagiterator_category;

typedefptrdiff_tdifference_type;

base_ptrnode;

//用来连接红黑树的节点

//寻找该节点的后继节点上

voidincrement()

if(node->

=0){//如果存在右子节点

node=node->

//直接跳到右子节点上

while(node->

=0)//然后一直往左子树走,直到左子树为空

else{//没有右子节点

base_ptry=node->

parent;

//找出父节点

while(node==y->

right){//如果该节点一直为它的父节点的右子节点

node=y;

//就一直往上找,直到不为右子节点为止

y=y->

=y)//若此时该节点不为它的父节点的右子节点

//此时的父节点即为要找的后继节点

//否则此时的node即为要找的后继节点,此为特殊情况,如下

//我们要寻找根节点的下一个节点,而根节点没有右子节点

//此种情况需要配合rbtree的header节点的特殊设计,后面会讲到

}

//寻找该节点你的前置节点

voiddecrement()

color==__rb_tree_red&

&

//如果此节点是红节点

node->

parent->

parent==node)//且父节点的父节点等于自己

//则其右子节点即为其前置节点

//以上情况发生在node为header时,即node为end()时

//注意:

header的右子节点为mostright,指向整棵树的max节点,后面会有解释

elseif(node->

=0){//如果存在左子节点

//跳到左子节点上

while(y->

=0)//然后一直往右找,知道右子树为空

//则找到前置节点

else{//如果该节点不存在左子节点

//跳到它的父节点上

left){//如果它等于它的父子节点的左子节点

//则一直往上查找

}//直到它不为父节点的左子节点未知

//此时他的父节点即为要找的前置节点

}

classValue,classRef,classPtr>

struct__rb_tree_iterator:

public__rb_tree_base_iterator

//配合迭代器萃取机制的一些声明

typedefValuevalue_type;

typedefRefreference;

typedefPtrpointer;

typedef__rb_tree_iterator<

Value,Value&

Value*>

iterator;

Value,constValue&

constValue*>

const_iterator;

Value,Ref,Ptr>

self;

//迭代器的构造函数

__rb_tree_iterator(){}

__rb_tree_iterator(link_typex){node=x;

__rb_tree_iterator(constiterator&

it){node=it.node;

//提领和成员访问函数,重载了*和->

操作符

referenceoperator*()const{returnlink_type(node)->

value_field;

pointeroperator->

()const{return&

(operator*());

//前置++和后置++

self&

operator++(){increment();

return*this;

selfoperator++(int){

selftmp=*this;

increment();

//直接调用increment函数

returntmp;

//前置--和后置--

operator--(){decrement();

selfoperator--(int){

decrement();

//直接调用decrement函数

在上述源代码中,一直提到STLRBTree特殊节点header的设计,这个会在RBTree结构中讲到,下面跟着我一起继续往下看吧。

红黑树的数据结构

有了上面的节点和迭代器设计,就能很好的定义出一颗RBTree了。

废话不多说,一步一步来剖析源代码吧。

classKey,classValue,classKeyOfValue,classCompare,

classAlloc=alloc>

classrb_tree{

protected:

typedefvoid*void_pointer;

rb_tree_node;

typedefsimple_alloc<

rb_tree_node,Alloc>

rb_tree_node_allocator;

//专属配置器

public:

//一些类型声明

typedefKeykey_type;

typedefvalue_type*pointer;

typedefconstvalue_type*const_pointer;

typedefvalue_type&

reference;

typedefconstvalue_type&

const_reference;

typedefrb_tree_node*link_type;

typedefsize_tsize_type;

//RB-tree的数据结构

size_typenode_count;

//记录树的节点个数

link_typeheader;

//header节点设计

Comparekey_compare;

//节点间的键值大小比较准则

//以下三个函数用来取得header的成员

link_type&

root()const{return(link_type&

)header->

leftmost()const{return(link_type&

rightmost()const{return(link_type&

//以下六个函数用来取得节点的成员

staticlink_type&

left(link_typex){return(link_type&

)(x->

left);

right(link_typex){return(link_type&

right);

parent(link_typex){return(link_type&

parent);

staticreferencevalue(link_typex){returnx->

staticconstKey&

key(link_typex){returnKeyOfValue()(value(x));

staticcolor_type&

color(link_typex){return(color_type&

color);

//以下六个函数用来取得节点的成员,由于双层设计,导致这里需要两个定义

left(base_ptrx){return(link_type&

right(base_ptrx){return(link_type&

parent(base_ptrx){return(link_type&

staticreferencevalue(base_ptrx){return((link_type)x)->

key(base_ptrx){returnKeyOfValue()(value(link_type(x)));

}

color(base_ptrx){return(color_type&

)(link_type(x)->

//求取极大值和极小值,这里直接调用节点结构的函数极可

staticlink_typeminimum(link_typex){

return(link_type)__rb_tree_node_base:

minimum(x);

staticlink_typemaximum(link_typex){

maximum(x);

//RBTree的迭代器定义

value_type,reference,pointer>

value_type,const_reference,const_pointer>

Comparekey_comp()const{returnkey_compare;

}//由于红黑树自带排序功能,所以必须传入一个比较器函数

iteratorbegin(){returnleftmost();

}//RBTree的起始节点为左边最小值节点

const_iteratorbegin()const{returnleftmost();

iteratorend(){returnheader;

}//RBTree的终止节点为右边最大值节点

const_iteratorend()const{returnheader;

boolempty()const{returnnode_count==0;

}//判断红黑树是否为空

size_typesize()const{returnnode_count;

}//获取红黑树的节点个数

size_typemax_size()const{returnsize_type(-1);

}//获取红黑树的最大节点个数,

//没有容量的概念,故为sizetype最大值

我们看到,在RBTree的数据结构中,定义了RBTree节点和迭代器,然后添加了header节点,以及node_count参数,其他都是一下简单的函数声明和类型声明。

除此之外,并没有过多的增加东西。

这里理解起来还是比较简单,至于header有什么作用,请继续往下看。

红黑树的构造与内存管理

红黑树的构造函数

红黑树的空构造函数将创建一个空树,此”空树“非彼二叉树的空树也。

空构造函数首先配置一个节点空间,使header指向该节点空间,然后将header的leftmost和rightmost指向自己,父节点指向0。

非空的STLRBTree中,header和root之间互为父节点,然后header的leftmost始终指向该树的最小值节点,rightmost始终指向该树的最大值节点,其示例图如下(左图为空树,右图为非空树):

下面来看看它的构造函数代码吧:

//这部分代码是从红黑树的结构定义中提取出来的

link_typeget_node(){returnrb_tree_node_allocator:

allocate();

}//配置空间

link_typecreate_node(constvalue_type&

x){

link_typetmp=get_node();

//配置空間

__STL_TRY{

construct(&

tmp->

value_field,x);

//构造内容

__STL_UNWIND(put_node(tmp));

//初始化函数,用来初始化一棵RBTree

voidinit(){

header=get_node();

//产生一个节点空间,令header指向它

color(header)=__rb_tree_red;

//令header为红色,用来区分header和root

root()=0;

leftmost()=header;

//令header的左子节点为其自己

rightmost()=header;

//令header的右子节点为其自己

//真正的默认构造函数

rb_tree(constCompare&

comp=Compare())

:

node_count(0),key_compare(comp){init();

}//直接调用初始化函数

//带参构造函数,以另一棵RBTree为初值来初始化

rb_tree(constrb_tree<

Key,Value,KeyOfValue,Compare,Alloc>

x)

node_count(0),key_compare(x.key_compare)

{

//產生一個節點空間,令header指向它

//令header為紅色

if(x.root()==0){//如果x是個空白樹

//令header的左子節點為自己。

//令header的右子節點為自己。

else{//x不是一個空白樹

root()=__copy(x.root(),header);

//调用copy函数

__STL_UNWIND(put_node(header));

leftmost()=minimum(root());

//令header的左子節點為最小節點

rightmost()=maximum(root());

//令header的右子節點為最大節點

node_count=x.node_count;

//copy函数定义

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1