[STL] 관련 용기 - 붉 은 검 은 나무
독립 용기
。용기 인 만큼 메모리 공간 (노드) 을 분배 하고 내부 에 도 교체 기 가 존재 한다.붉 은 검 은 나무의 일부 성질 에 대해 서 는 '데이터 구조' 중의 필 기 를 참고 할 수 있 으 며, 여기 에는 STL 의 붉 은 검 은 나무 가 어떻게 실현 되 었 는 지 만 기록 되 어 있다.
slist 와 마찬가지 로 빨 간 검 은 나무의 노드 와 교체 기 는 모두 이중 구 조 를 사용 했다.
노드:rb_tree_node 상속 자rb_tree_node_base
교체 기:rb_tree_iterator 상속 자rb_tree_base_iterator
먼저 색상 표 지 를 보 세 요.
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; // RB
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; //
void increment() // ++
{
....
}
void decrement() // --
{
....
}
};
기본 교체 기 에서 node 구성원 을 주의 하고 그 다음 에 operator + 와 operator - 를 제공 하 는 내부 방법 입 니 다. 그들 은 빨 간 검 은 나무 특성 에 따라 node 가 뒤의 하나 또는 앞의 노드 를 가리 키 게 합 니 다. 빨 간 검 은 나 무 는 이 진 트 리 이기 때문에 키 값 이 인접 한 노드 를 찾 는 것 은 규칙 적 으로 따라 갈 수 있 습 니 다.그래서 붉 은 검 은 나무의 교체 기 는 양 방향 교체 기 에 속한다.
상층 교체 기:
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; } // node
__rb_tree_iterator(const iterator& it) { node = it.node; }
reference operator*() const { return link_type(node)->value_field; } // , link_type
pointer operator->() const { return &(operator*()); } //
self& operator++() { increment(); return *this; }
self operator++(int) {
....
}
self& operator--() { decrement(); return *this; }
self operator--(int) {
....
}
};
상층 교체 기 는 빨 간 검 은 나무 류 의 교체 기 입 니 다. 그 + 또는 - 작업 은 결국 기본 교체 기 중의 increment () 또는 decrement () 를 호출 했 습 니 다.
다음은 빨 간 검 은 나무의 데이터 구조 구 조 를 기록 합 니 다.
template <class Key, class Value, class KeyOfValue, class Compare,
class Alloc = alloc>
class rb_tree {
....
typedef __rb_tree_node<Value> rb_tree_node;
typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator; // ,
typedef rb_tree_node* link_type;
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();
construct(&tmp->value_field, x);
return tmp;
}
....
void destroy_node(link_type p) { //
destroy(&p->value_field);
put_node(p);
}
protected:
size_type node_count; //
link_type header; //
Compare key_compare; //
....
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 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:
pair<iterator,bool> insert_unique(const value_type& x); //
iterator insert_equal(const value_type& x); //
void erase(iterator position); //
....
public:
// multimap multiset
iterator find(const key_type& x);
size_type count(const key_type& x) const;
iterator lower_bound(const key_type& x);
iterator upper_bound(const key_type& x);
pair<iterator,iterator> equal_range(const key_type& x);
}
위 코드 의 빨간색 부분 은 노드 가 루트 일 때의 경계 상황 을 처리 하 는 기술 을 사 용 했 습 니 다. 이것 은 header 지침 을 사 용 했 습 니 다.헤더 초기 화 함수 먼저 보기:
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; }
void init() { // header
header = get_node();
color(header) = __rb_tree_red; // used to distinguish header from
// root, in iterator.operator--
root() = 0; // header->parent = null
leftmost() = header;
rightmost() = header;
}
header 가 가리 키 는 노드 의 색 을 빨간색 (뿌리 노드 의 검은색 을 구별 하기 위해) 으로 설정 합 니 다. 이것 은 뿌리 노드 가 아니 라 보초병 노드 와 유사 합 니 다.header 의 parent 는 루트 를 가리 키 고 있 습 니 다. (여기 서 null 로 초기 화 됨)left 는 항상 최소 노드 를 가리킨다.right 는 항상 최대 노드 를 가리킨다.header 가 이 정 보 를 기록 한 후에 용기 의 begin (), end () 는 잘 구 할 수 있 습 니 다.
iterator begin() { return leftmost(); } // header->left
iterator end() { return header; } // header, __rb_tree_iterator
다른 용기 와 마찬가지 로 end () 역시 마지막 요소 (최대 노드) 의 다음 노드 를 되 돌려 줍 니 다.
참고:
《 STL 소스 분석 》 P213.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.