vector:
vector维护的是一个连续的线性空间,所以不论其元素型别为何,普通指针都可以作为vector的迭代器。vector的主要数据结构如下:
template<class T,class Alloc=alloc>
class vector{
...
typedef value_type* iterator;
...
iterator start;
iterator finish;
iterator end_of_storage;
}
list
相较于vector的线性连续空间,list就显得复杂许多,特它的好处是每次插入或删除一个元素,就释放或配置一个元素空间。因此list对于空间的利用绝对精准,一点也不浪费。list的主要数据结构如下所示:
template <class T> //节点结构
struct __list_node {
typedef void* void_pointer;
void_pointer next;
void_pointer prev;
T data;
};
template<class T, class Ref, class Ptr> //迭代器结构
struct __list_iterator {
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
...
typedef bidirectional_iterator_tag iterator_category;
typedef __list_node<T>* link_type;
link_type node; //指向节点的指针
__list_iterator(link_type x) : node(x) {}
__list_iterator() {}
__list_iterator(const iterator& x) : node(x.node) {}
...
}
template <class T, class Alloc = alloc>
class list {
protected:
typedef __list_node<T> list_node;
typedef list_node* link_type;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
protected:
link_type node; //唯一的数据成员,是个指向空白节点的指针,通过这个空白节点list成为环形双向链表
public:
list() { empty_initialize(); }//list的所有构造函数都会调用empty_initialize,创建一个空白节点
protected:
void empty_initialize() { //创建一个空白节点
node = get_node();
node->next = node;
node->prev = node;
}
iterator begin() { return (link_type)((*node).next); }
const_iterator begin() const { return (link_type)((*node).next); }
iterator end() { return node; }
const_iterator end() const { return node; }
...
}
deque
deque是一种双向开口的连续(分段连续)空间。deque没有容量的概念,因为它是动态的分段连续空间组合而成,随时可以增加一段新的空间并链接起来。也因此deque没有必要提供所谓的空间保留功能。deque最大的任务便是在这些分段连续的空间上,维护其整体连续的假象。deque的主要数据结构如下:
template <class T, class Ref, class Ptr, size_t BufSiz>
struct __deque_iterator {
public:
typedef T** map_pointer;
T* cur;
T* first;
T* last;
map_pointer node;
__deque_iterator(T* x, map_pointer y)
: cur(x), first(*y), last(*y + buffer_size()), node(y) {}
__deque_iterator() : cur(0), first(0), last(0), node(0) {}
__deque_iterator(const iterator& x)
: cur(x.cur), first(x.first), last(x.last), node(x.node) {}
void set_node(map_pointer new_node) {
node = new_node;
first = *new_node;
last = first + difference_type(buffer_size());
}
}
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public: // Basic types
typedef T value_type;
typedef value_type* pointer;
public:
typedef __deque_iterator<T, T&, T*, BufSiz> iterator;
typedef __deque_iterator<T, const T&, const T&, BufSiz> const_iterator;
protected: // Internal typedefs
typedef pointer* map_pointer;
typedef simple_alloc<value_type, Alloc> data_allocator;
typedef simple_alloc<pointer, Alloc> map_allocator;
protected: // Data members
iterator start;
iterator finish;
map_pointer map;
size_type map_size;
public: // Basic accessors
iterator begin() { return start; }
iterator end() { return finish; }
const_iterator begin() const { return start; }
const_iterator end() const { return finish; }
}
map成员管理的节点数由插入的元素数量与缓冲区(默认为512bytes)的大小有关,最少为8个,最多是“所需节点数加2”,前后各预留一个,扩充空间时用。
create_map_and_nodes(size_type num_elements) {
size_type num_nodes = num_elements / buffer_size() + 1;
map_size = max(initial_map_size(), num_nodes + 2);
map = map_allocator::allocate(map_size);
map_pointer nstart = map + (map_size - num_nodes) / 2;
map_pointer nfinish = nstart + num_nodes - 1;
map_pointer cur;
__STL_TRY {
for (cur = nstart; cur <= nfinish; ++cur)
*cur = allocate_node();
}
插入元素时首先观察缓冲区是否有空间,如果缓冲区没有空间则需要配置一块新的缓冲区。
void push_back(const value_type& t) {
if (finish.cur != finish.last - 1) { //最后的缓冲器有两个以上的备用空降
construct(finish.cur, t);
++finish.cur;
}
else
push_back_aux(t); //最后缓冲器只剩一个元素的备用空间
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
value_type t_copy = t;
reserve_map_at_back(); //是否需要重换一个map
*(finish.node + 1) = allocate_node();
__STL_TRY {
construct(finish.cur, t_copy);
finish.set_node(finish.node + 1);
finish.cur = finish.first;
}
__STL_UNWIND(deallocate_node(*(finish.node + 1)));
}
分配新的缓冲区时可能需要重新分配map结构:
void reserve_map_at_back (size_type nodes_to_add = 1) {
if (nodes_to_add + 1 > map_size - (finish.node - map))
reallocate_map(nodes_to_add, false);
}
priority_queue:
优先队列是一个具有权值观念的队列,允许新元素的加入,旧元素的移除。由于是一个队列,所以只允许在低端加入元素push,从顶端取出元素pop,top。优先队列是以一系列max-heap完成,厚泽是以一个vector表现的完全二叉树。
template <class T, class Sequence = vector<T>,
class Compare = less<typename Sequence::value_type> >
class priority_queue {
public:
typedef typename Sequence::value_type value_type;
protected:
Sequence c;
Compare comp;
public:
priority_queue() : c() {}
explicit priority_queue(const Compare& x) : c(), comp(x) {}
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last, const Compare& x)
: c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); }
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
priority_queue(const value_type* first, const value_type* last,
const Compare& x) : c(first, last), comp(x) {
make_heap(c.begin(), c.end(), comp);
}
priority_queue(const value_type* first, const value_type* last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
const_reference top() const { return c.front(); }
void push(const value_type& x) {
{
c.push_back(x);
push_heap(c.begin(), c.end(), comp);
}
}
void pop() {
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
}
}
};
list是环形双向链表,slist是单向链表。
struct __slist_node_base
{
__slist_node_base* next;
};
template <class T>
struct __slist_node : public __slist_node_base
{
T data;
};
struct __slist_iterator_base
{
typedef size_t size_type;
typedef forward_iterator_tag iterator_category;
__slist_node_base* node; //指向节点基本结构
__slist_iterator_base(__slist_node_base* x) : node(x) {}
};
template <class T, class Ref, class Ptr>
struct __slist_iterator : public __slist_iterator_base
{
typedef __slist_iterator<T, T&, T*> iterator;
typedef __slist_iterator<T, const T&, const T*> const_iterator;
typedef __slist_iterator<T, Ref, Ptr> self;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __slist_node<T> list_node;
__slist_iterator(list_node* x) : __slist_iterator_base(x) {}
__slist_iterator() : __slist_iterator_base(0) {}
__slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
reference operator*() const { return ((list_node*) node)->data; }
pointer operator->() const { return &(operator*()); }
};
template <class T, class Alloc = alloc>
class slist
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef __slist_iterator<T, T&, T*> iterator;
typedef __slist_iterator<T, const T&, const T*> const_iterator;
private:
typedef __slist_node<T> list_node;
typedef __slist_node_base list_node_base;
typedef __slist_iterator_base iterator_base;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
private:
list_node_base head; //实物,不是指针
public:
iterator begin() { return iterator((list_node*)head.next); }
iterator end() { return iterator(0); }
}