主要分析一下STL裏的紅黑樹,紅黑樹相對來說是一種較爲複雜的數據結構,具體的學習方法建議看那種帶有很多圖解的博客,先理解其原理流程,再自己寫下代碼,其實就能理解了。STL裏紅黑樹的實現有幾個特點,一個它設置了一個空頭結點header,它的左節點指向樹最小元素,有節點指向樹最大元素,實際帶有有意義值的頭結點爲root,root的父節點爲header.這使在一些插入刪除操作時要討論下特殊情況,附上代碼分析
//紅色爲false,黑色爲true
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red = false;
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;
//迭代器種類爲bidirectional_iterator
typedef bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
base_ptr node;
//尋找後繼節點
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()
{
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;
}
};
template <class Key, class Value, class KeyOfValue, class Compare,
class Alloc = alloc>
/* key紅黑樹上存儲節點時依據的值
* value節點的值
* KeyOfValue仿函數
* Compare爲比較key大小的標準
* Alloc空間配置器
*/
class rb_tree {
protected:
typedef void *void_pointer;
typedef __rb_tree_node_base *base_ptr;
typedef __rb_tree_node<Value> rb_tree_node;
//自帶的配置函數
typedef simple_alloc <rb_tree_node, Alloc> rb_tree_node_allocator;
typedef __rb_tree_color_type color_type;
public:
typedef Key key_type;
typedef Value value_type;
typedef value_type *pointer;
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
typedef rb_tree_node *link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
//獲取一個新的節點
link_type get_node() { return rb_tree_node_allocator::allocate(); }
//釋放指定節點
void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); }
//創建一個節點,先申請內存然後構造
link_type create_node(const value_type &x) {
link_type tmp = get_node();
__STL_TRY{
construct(&tmp->value_field, x);
}
__STL_UNWIND(put_node(tmp));
return tmp;
}
//複製節點
link_type clone_node(link_type x) {
link_type tmp = create_node(x->value_field);
tmp->color = x->color;
tmp->left = 0;
tmp->right = 0;
return tmp;
}
//銷燬節點
void destroy_node(link_type p) {
destroy(&p->value_field);
put_node(p);
}
protected:
size_type node_count;
//header節點
link_type header;
//大小比較函數
Compare key_compare;
//獲取頭結點
link_type &root() const { return (link_type &) header->parent; }
//獲取最小節點
link_type &leftmost() const { return (link_type &) header->left; }
//獲取最大節點
link_type &rightmost() const { return (link_type &) header->right; }
//返回當前節點的左孩子
static link_type &left(link_type x) { return (link_type &) (x->left); }
static link_type &right(link_type x) { return (link_type &) (x->right); }
static link_type &parent(link_type x) { return (link_type &) (x->parent); }
//獲取當前節點的value
static reference value(link_type x) { return x->value_field; }
//通過value獲取當前節點的key
static const Key &key(link_type x) { return KeyOfValue()(value(x)); }
//獲取當前節點的顏色
static color_type &color(link_type x) { return (color_type &) (x->color); }
static link_type &left(base_ptr x) { return (link_type &) (x->left); }
static link_type &right(base_ptr x) { return (link_type &) (x->right); }
static link_type &parent(base_ptr x) { return (link_type &) (x->parent); }
static reference value(base_ptr x) { return ((link_type) x)->value_field; }
static const Key &key(base_ptr x) { return KeyOfValue()(value(link_type(x))); }
static color_type &color(base_ptr x) { return (color_type &) (link_type(x)->color); }
//獲取最小值和最大值
static link_type minimum(link_type x) {
return (link_type) __rb_tree_node_base::minimum(x);
}
static link_type maximum(link_type x) {
return (link_type) __rb_tree_node_base::maximum(x);
}
public:
typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
typedef __rb_tree_iterator<value_type, const_reference, const_pointer>
const_iterator;
private:
//插入
iterator __insert(base_ptr x, base_ptr y, const value_type &v);
//複製
link_type __copy(link_type x, link_type p);
//刪除
void __erase(link_type x);
//初始化,申請一空頭結點
void init() {
header = get_node();
color(header) = __rb_tree_red;
root() = 0;
leftmost() = header;
rightmost() = header;
}
public:
//構造函數
rb_tree(const Compare &comp = Compare())
: node_count(0), key_compare(comp) { init(); }
//拷貝構造函數
rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &x)
: node_count(0), key_compare(x.key_compare) {
header = get_node();
color(header) = __rb_tree_red;
if (x.root() == 0) {
root() = 0;
leftmost() = header;
rightmost() = header;
} else {
__STL_TRY{
root() = __copy(x.root(), header);
}
__STL_UNWIND(put_node(header));
leftmost() = minimum(root());
rightmost() = maximum(root());
}
node_count = x.node_count;
}
~rb_tree() {
clear();
put_node(header);
}
//重載操作符=,即賦值
rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &
operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &x);
//重載操作符==
template<class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &x,
const rb_tree<Key, Value, KeyOfValue, Compare, Alloc> &y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
public:
Compare key_comp() const { return key_compare; }
//起始迭代器是最小節點,即header結點的左節點
iterator begin() { return leftmost(); }
const_iterator begin() const { return leftmost(); }
//末尾迭代器是header
iterator end() { return header; }
const_iterator end() const { return header; }
//判斷是否爲空
bool empty() const { return node_count == 0; }
//節點個數
size_type size() const { return node_count; }
size_type max_size() const { return size_type(-1); }
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
__insert(base_ptr x_, base_ptr y_, const Value& v) {
/* x爲新的插入點
* y爲要插入的點的父節點
* v爲插入的值
*/
link_type x = (link_type) x_;
link_type y = (link_type) y_;
link_type z;
//y爲header或x不爲空或者要插入的值的key與y不重複
if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) {
//創建並初始化值爲v的節點,爲紅色
z = create_node(v);
//將header的左孩子設置爲z
left(y) = z;
if (y == header) {
root() = z;
rightmost() = z;
}
else if (y == leftmost())
leftmost() = z;
}
else {
//否則創建值爲v的節點
z = create_node(v);
//將y的右孩子設置爲z
right(y) = z;
//更新最大點
if (y == rightmost())
rightmost() = z;
}
//設置新節點的父節點、左孩子節點、右孩子節點
parent(z) = y;
left(z) = 0;
right(z) = 0;
//平衡調節
__rb_tree_rebalance(z, header->parent);
//節點數加1
++node_count;
//返回迭代器指向新增節點
return iterator(z);
}
//左旋
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)
//將左子節點的父節點設置爲x
y->left->parent = x;
y->parent = x->parent;
//將x的位置替換成y
if (x == root)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}