本文算是上一篇STL set学习的后续。主要是review代码的时候,接着对set进行了讨论,需要明白set到底是如何进行insert和find的。因此,简单地研究了一下stl代码,set是基于RB-tree(红黑树)实现的。上网查了相关的资料,都写得不好,包括那些所谓“真正让你了解红黑树”的文章,都不如直接读源代码理解来得快,有《STL源码剖析》的帮助,比网上任何资料都更加明白。也真正明白上一篇set中第3点所说的排序规则,在RB-tree中是如何实现的了。简单做了些笔记,post上来。
1. 平衡二叉搜索树 (balance binary search tree)
2. AVL树:Adelson-Velskii-Landis tree又是以人名命名的——就是原来学的平衡二叉树
这是一个弱二叉平衡树,即左右子树的高度相差最多为1,用以保证“对数深度” O(logN)的平衡状态
左左,右右的单旋转
左右,右左的双旋转
3. RB-tree: 红黑树,是AVL的一种,被广泛使用
是SGI STL唯一实现的一种搜索树,作为关联式容器(associated contrainers)的底部机制
必须满足以下规则:

也就是说,要插入一个节点,首先得根据二叉搜索树的规则,找到插入点(从root节点开始,左小右大的规则)
找到之后再根据RB-tree的规则,进行颜色的调整,以及位置旋转,旋转过后可能还需要改变颜色。
4. 对于set容器,底层实现是由RB-tree实现的,是调用了stl_tree.h里RB-tree的insert, delete, find的操作
调用insert_unique(), insert的规则如下:(即实现代码,来自STL源码剖析-侯捷)

解释:x为当前树中的节点,v为即将插入的新节点,离开while时,y为插入点的父节点
此时,已调用一次operator<()来比较v和y的大小
1)如果上一次v < y,若,y是最左节点,则v插入到y的左侧,insert(v) to y
若,y不是最左节点,则回到y的上一节点,走2)
2)如果上一次v >= y, 或者v<y但y不是最左节点,则走2)
再次调用operator<()来比较y和v的大小,如果y < v, 说明v将插入到y的右侧
如果 y >= v,则说明y == v,即键值重复
5. find()操作
注意,也是进行两次比较,x为树中节点,k为新节点,第一次比较x < k?
第二次比较k < x?
