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

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()。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值