标签:
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()。
标签:
原文地址:http://blog.csdn.net/yao_wust/article/details/44199807