关联式容器
-
分为set 和map两大类及其衍生体。所有容器底层均是RB-tree红黑树(这也是一个独立容器,但是不开放给外界使用);此外还提供hash table 及以它为底层完成的hash_set , hash_map , hash_multiset , hash_multimap
-
每笔数据(每个元素)都有一个键值key和一个实值value,内部按照key大小按照某种规则放在适当位置,故没有所谓的头尾。
树
-
一些基本术语
-
二叉搜索树:插入删除
-
平衡二叉搜索树:插入删除更麻烦,但搜索节省25%左右时间
-
AVL tree:深度O(logN)
-
单旋转
-
双旋转
RB-tree
-
是二叉搜索树;节点非红即黑;根节点黑色;若节点红,子节点必黑;任一节点至NULL(树尾端)的任何路径,所含黑节点树必然相同
-
插入节点
- 状况一:
- 状况二:第二次调整是因为不满足根节点是黑色的规则?还是为了相对平衡
- 状况三:
- 状况四:
- 状况一:
-
一个由上而下的程序
之后节点35的插入就很单纯了:要么直接插入,要么插入后再一次旋转
-
迭代器设计非常关键。SGI 将迭代器设计为两层(与slist相似): _ rb_tree node继承自 rb_tree _node _base, _ _rb_tree node iterator继承自 rb_tree _node _base __iterator.
双向迭代器,但不具备随即定位的能力。 -
++和–中令人费解的边界操作:
其中header(特别为根节点再设计的)的定义如下:
-
注意,真实实现时,外侧只依次调整颜色,内侧才进行双旋,和上面的不一样
#ifndef __SGI_STL_INTERNAL_TREE_H
#define __SGI_STL_INTERNAL_TREE_H
#include <stl_algobase.h>
#include <stl_alloc.h>
#include <stl_construct.h>
#include <stl_function.h>
__STL_BEGIN_NAMESPACE
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red = false; //红为0,黑为1
const __rb_tree_color_type __rb_tree_black = true;
struct __rb_tree_node_base
{
typedef __rb_tree_color_type color_type;
typedef __rb_tree_node_base* base_ptr;
color_type color; //节点颜色
base_ptr parent; //父节点
base_ptr left;
base_ptr right;
static base_ptr minimum(base_ptr x)
{//一直向左走即可
while (x->left != 0) x = x->left;
return x;
}
static base_ptr maximum(base_ptr x)
{//一直向右走即可
while (x->right != 0) x = x->right;
return x;
}
};
template <class Value>
struct __rb_tree_node : public __rb_tree_node_base //继承!不是组合
{
typedef __rb_tree_node<Value>* link_type;
Value value_field;//结点值
};
//基层迭代器
struct __rb_tree_base_iterator
{
typedef __rb_tree_node_base::base_ptr base_ptr;
typedef bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
base_ptr node;//用来与容器之间产生一个联结
//只有operator++调用了此函数
//该函数对着画的图就能看懂了,若无右节点且身为左子树,父节点即为所求
//若为右子树,则向上追溯到不为右子树的点,然后转向其父节点(拐个弯)即为所求
void increment()
{
if (node->right != 0) {//有右节点
node = node->right;//下一个就是右子树的最左节点
while (node->left != 0)
node = node->left;
}
else {
base_ptr y = node->parent;
while (node == y->right) {//该结点不为右节点
node = y;
y = y->parent;
}
if (node->right != y)//右子节点不等于父节点为了应付根节点情况
node = y;//父节点即为所求
}
}
void decrement()
{
//当node为header时,即end(),header右节点为mostright,指向max节点
if (node->color == __rb_tree_red &&
node->parent->parent == node)
node = node->right;
else if (node->left != 0) {
base_ptr y = node->left;
while (y->right != 0)
y = y->right;
node = y;
}
else {
base_ptr y = node->parent;
while (node == y->left) {
node = y;
y = y->parent;
}
node = y;
}
}
};
//正规迭代器
template <class Value, class Ref, class Ptr>
struct __rb_tree_iterator : public __rb_tree_base_iterator
{
typedef Value value_type;
typedef Ref reference;
typedef Ptr pointer;
typedef __rb_tree_iterator<Value, Value&, Value*> iterator;
typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;
typedef __rb_tree_iterator<Value, Ref, Ptr> self;
typedef __rb_tree_node<Value>* link_type;
__rb_tree_iterator() {}
__rb_tree_iterator(link_type x) { node = x; }
__rb_tree_iterator(const iterator& it) { node = it.node; }
reference operator*() const { return link_type(node)->value_field; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
self& operator++() { increment(); return *this; }
self operator++(int) {
self tmp = *this;
increment();
return tmp;
}
self& operator--() { decrement(); return *this; }
self operator--(int) {
self tmp = *this;
decrement();
return tmp;
}
};
inline bool operator==(const __rb_tree_base_iterator& x,
const __rb_tree_base_iterator& y) {
return x.node == y.node;
}
inline bool operator!=(const __rb_tree_base_iterator& x,
const __rb_tree_base_iterator& y) {
return x.node != y.node;
}
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
inline bidirectional_iterator_tag
iterator_category(const __rb_tree_base_iterator&) {
return bidirectional_iterator_tag();
}
inline __rb_tree_base_iterator::difference_type*
distance_type(const __rb_tree_base_iterator&) {
return (__rb_tree_base_iterator::difference_type*) 0;
}
template <class Value, class Ref, class Ptr>
inline Value* value_type(const __rb_tree_iterator<Value, Ref, Ptr>&) {
return (Value*) 0;
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
//类似右旋,不再赘述
inline void
__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root)
{
__rb_tree_node_base* y = x->right;
x->right = y->left;
if (y->left !=0)
y->left->parent = x;
y->parent = x->parent;
if (x == root)
root = y;
else if (x =&#