STL原始碼分析RB-tree關聯容器 下
阿新 • • 發佈:2018-12-08
前言
上節我們分析了關於RB-tree的迭代器實現, 其中最重要的功能都會在rb-tree結構中呼叫. 本節我們就來分析RB-tree
結構.
再來複習一下紅黑樹的規則:
- 每個節點的顏色是黑色或者紅色
- 根節點必須是黑色的
- 每個葉節點(NULL)必須是黑色的
- 如果節點是紅色的, 則子節點必須是黑色的
- 從節點到每個子孫節點的路徑包括的黑色節點數目相同
// 紅黑定義
typedef bool __rb_tree_color_type;
const __rb_tree_color_type __rb_tree_red = false;
const __rb_tree_color_type __rb_tree_black = true;
RB-tree結構分析
rb-tree型別定義
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = 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:
// 滿足traits程式設計
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:
size_type node_count; // keeps track of size of tree
link_type header; // 頭節點, 不是根節點, 頭節點是指向根節點
Compare key_compare; // 偽函式
public:
// 定義迭代器
typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
typedef __rb_tree_iterator<value_type, const_reference, const_pointer>
const_iterator;
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
typedef reverse_bidirectional_iterator<iterator, value_type, reference,
difference_type>
reverse_iterator;
typedef reverse_bidirectional_iterator<const_iterator, value_type,
const_reference, difference_type>
const_reverse_iterator;
...
};
構造解構函式
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = alloc>
class rb_tree {
...
public: // allocation/deallocation
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) { // 如果x為根節點
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); // 釋放所有空間
}
...
};
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = alloc>
class rb_tree {
...
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);
}
private:
void init() {
header = get_node();
color(header) = __rb_tree_red; // used to distinguish header from
// root, in iterator.operator++
root() = 0;
leftmost() = header;
rightmost() = header;
}
public:
void clear() {
if (node_count != 0) {
__erase(root());
leftmost() = header;
root() = 0;
rightmost() = header;
node_count = 0;
}
}
...
};
節點屬性
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = alloc>
class rb_tree {
...
protected:
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); }
static reference value(link_type x) { return x->value_field; } // 當前節點的資料
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:
// accessors:
Compare key_comp() const { return key_compare; }
// begin() 獲取的是最小節點
iterator begin() { return leftmost(); }
const_iterator begin() const { return leftmost(); }
// end() 頭節點
iterator end() { return header; }
const_iterator end() const { return header; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
bool empty() const { return node_count == 0; } // 樹為空
size_type size() const { return node_count; } // 節點計數
size_type max_size() const { return size_type(-1); }
...
};
swap
rb-tree交換也並不是交換所有的節點, 只是交換了頭節點, 節點數和比較偽函式.
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = alloc>
class rb_tree {
...
public:
void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) {
__STD::swap(header, t.header);
__STD::swap(node_count, t.node_count);
__STD::swap(key_compare, t.key_compare);
}
...
};
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
inline void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x,
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
x.swap(y);
}
過載
// 相等比較
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());
}
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 lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
// 過載=運算子
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>&
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) {
if (this != &x) {
// Note that Key may be a constant type.
clear(); // 清除所有節點
node_count = 0;
key_compare = x.key_compare;
// 將每個節點進行賦值
if (x.root() == 0) {
root() = 0;
leftmost() = header;
rightmost() = header;
}
else {
root() = __copy(x.root(), header);
leftmost() = minimum(root());
rightmost() = maximum(root());
node_count = x.node_count;
}
}
return *this;
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = alloc>
class rb_tree {
...
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);
public:
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>&
operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x);
public:
// insert/erase
pair<iterator,bool> insert_unique(const value_type& x);
iterator insert_equal(const value_type& x);
iterator insert_unique(iterator position, const value_type& x);
iterator insert_equal(iterator position, const value_type& x);
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert_unique(InputIterator first, InputIterator last);
template <class InputIterator>
void insert_equal(InputIterator first, InputIterator last);
#else /* __STL_MEMBER_TEMPLATES */
void insert_unique(const_iterator first, const_iterator last);
void insert_unique(const value_type* first, const value_type* last);
void insert_equal(const_iterator first, const_iterator last);
void insert_equal(const value_type* first, const value_type* last);
#endif /* __STL_MEMBER_TEMPLATES */
void erase(iterator position);
size_type erase(const key_type& x);
void erase(iterator first, iterator last);
void erase(const key_type* first, const key_type* last);
public:
// set operations:
iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
size_type count(const key_type& x) cons