码迷,mamicode.com
首页 > 其他好文 > 详细

《STL源码剖析》读书笔记之关联式容器(1)

时间:2015-03-13 10:58:13      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

1.AVL树

     AVL tree是指任何节点的左右子树高度相差最多1的二叉搜索树。任何节点左右子树高度最多相差1能够保证AVL树具有“对数深度”的平衡状态。在对AVL tree进行插入操作时,可能造成树平衡被破坏。根据新结点插入位置的不同,可以将平衡的破坏分成四种情况:左左,左右,右左,右右。其中左左和右右被称为外侧插入,可以采用单旋转操作调制解决。而左右和右左则称为内侧插入,可以采用双旋转操作调整解决。

单旋转:

技术分享

双旋转:

技术分享

2.RB-tree

     RB-tree是另外一个被广泛应用的平衡二叉搜索树,也是STL唯一实现的一种搜索树。作为关联式容器的底部机制,RB-tree虽然不同与AVL-tree,但同样运用了单旋转和双旋转操作。

     RB-tree是一个满足如下四个条件的二叉搜索树:

     1.每个节点不是红色就是黑色。

     2.根节点为黑色。

     3.如果节点为红,则其父节点必须为黑。

     4.任何一个节点至树尾端的任何路径所含黑节点必须相同。

     如果新增节点之后,树不再符合上述规则,就必须调整颜色并旋转树形。

(1)RB-tree的节点设计

     RB-tree有红黑二色,并且有左右子节点,且节点的各种操作都要上溯到其父节点,所以不能定义其数据结构应该如下:

技术分享


技术分享

(2)RB-tree的迭代器

     RB-tree迭代器属于双向迭代器,但不具备随机定位能力,其操作与list十分相似。迭代器的前进和后退操作完全依据二叉树的节点排序法则。

     前进操作:

技术分享

     后退操作:

技术分享

技术分享

(3)RB-tree的构造与内存管理

     RB-tree所定义的专属空间配置器rb_tree_node_allocator,每次可以配置一个节点。

技术分享

     构造RB-tree有两种方式:一种是以现有的RB-tree复制一个新的RB-tree,另一个是产生一颗空树。


(4)RB-tree元素的操作

     根据允不允许树中有相同的元素,RB-tree的插入操作分为insert_equal()和insert_unique(),其依托的底层操作都是函数_insert()。插入新节点后,可能导致RB-tree不平衡。需要调用_rb_tree_rebalance()函数使树重新变得平衡。在进行调整是,有时要调整节点颜色,有时要做单旋转,有时要双旋转。某些时候要左旋,某些时候要右旋(分别调用_rb_tree_rotate_left()和_rb_tree_rotate_right())。

    

(3)set

     set的特性是,所有的元素会根据元素的键值自动被排序。set的元素不像map一样可以同时拥有实值和键值,且set不允许两个元素有相同的键值。我们不能通过set的迭代器来改变set的元素。因为在STL中,set的底层实现机制是RB-tree,改变RB-tree上的元素会造成RB-tree不合法。

     当在set中增加元素或者删除元素时,操作之前的所有迭代器,在操作之后都依然有效(除了被删除的那个元素)。


(4)map

     map跟set一样,其所有元素也都会根据元素的键值自动被排序。map的所有元素都是pair,同时拥有实值和键值,map不允许两个元素拥有相同的实值。我们不能通过map的迭代器来更改map的键值,但我们可以通过迭代器来修改map的实值。


(5)multiset

     multiset的特性与用法和set完全相同,唯一的差别在于它允许键值重复,所以它的插入操作用的是RB-tree的insert_equal()而非insert_unique()。


(6)multimap

     multimap的特性与用法和set完全相同,唯一的差别在于它允许键值重复,所以它的插入操作用的是RB-tree的insert_equal()而非insert_unique()。


《STL源码剖析》读书笔记之关联式容器(1)

标签:

原文地址:http://blog.csdn.net/yao_wust/article/details/44199807

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!