序列式容器
Vector
vector的数据安排以及操作方式,与array非常相似,两者的唯一差别就是空间的运用的灵活性。array是静态空间,一旦配置就不能改变。vector是动态空间,随着元素的加入,它的内部机制会自行扩充以容纳新元素。
Vector的基类_Vector_base
template <class _Tp, class _Alloc>
class _Vector_base {
public:
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Vector_base(const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
_Vector_base(size_t __n, const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
protected:
//Vector中数据起始位置
_Tp* _M_start;
//Vector中数据结束位置
_Tp* _M_finish;
//Vector空间结束位置
_Tp* _M_end_of_storage;
//Vector中分配内存的类,会根据分配数据大小(128k)决定是否使用内存池分配
typedef simple_alloc<_Tp, _Alloc> _M_data_allocator;
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ _M_data_allocator::deallocate(__p, __n); }
};
主要定义了Vector内存相关数据和接口。
Vector类继承_Vector_base类
class vector : protected _Vector_base<_Tp, _Alloc>
{
private:
typedef _Vector_base<_Tp, _Alloc> _Base;
}
Vector接口函数
Begin和end函数直接返回内存数据的起始和结束地址
iterator begin() { return _M_start; }
const_iterator begin() const { return _M_start; }
iterator end() { return _M_finish; }
const_iterator end() const { return _M_finish; }
size和capacity函数返回finish和storage相对于begin的位置
size_type size() const
{ return size_type(end() - begin()); }
size_type max_size() const
{ return size_type(-1) / sizeof(_Tp); }
size_type capacity() const
{ return size_type(_M_end_of_storage - begin()); }
Reserve函数
- 检查参数,需要分配大小
- 分配内存并且拷贝旧数据
- 删除旧数据的内存
- 将_M_start,_M_finish,_M_end_of_storage指向新内存。
vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
void reserve(size_type __n) {
if (capacity() < __n) {
const size_type __old_size = size();
iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_finish = __tmp + __old_size;
_M_end_of_storage = _M_start + __n;
}
}
Vector在指定位置插入数据函数
- 判断Vector是否有剩余空间
- 有空间的情况下通过内存拷贝将数据拷贝到指定位置
- 没有空间的情况下重新申请内存,并将原始数据和新添加的数据拷贝到新的内存
- 重新申请内存按照旧内存的2倍申请,1,2,4,8
template <class _Tp, class _Alloc>
void
vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
{
if (_M_finish != _M_end_of_storage) {
construct(_M_finish, *(_M_finish - 1));
++_M_finish;
_Tp __x_copy = __x;
copy_backward(__position, _M_finish - 2, _M_finish - 1);
*__position = __x_copy;
}
else {
const size_type __old_size = size();
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
iterator __new_start = _M_allocate(__len);
iterator __new_finish = __new_start;
__STL_TRY {
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
construct(__new_finish, __x);
++__new_finish;
__new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
}
__STL_UNWIND((destroy(__new_start,__new_finish),
_M_deallocate(__new_start,__len)));
destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __new_start;
_M_finish = __new_finish;
_M_end_of_storage = __new_start + __len;
}
}
Pushback函数
只有当重新申请内存时会发生内存拷贝
void push_back(const _Tp& __x) {
if (_M_finish != _M_end_of_storage) {
construct(_M_finish, __x);
++_M_finish;
}
else
_M_insert_aux(end(), __x);
}
Insert函数
当插入的数据不再end位置或者超出Vector内存时发生内存拷贝
iterator insert(iterator __position, const _Tp& __x) {
size_type __n = __position - begin();
if (_M_finish != _M_end_of_storage && __position == end()) {
construct(_M_finish, __x);
++_M_finish;
}
else
_M_insert_aux(__position, __x);
return begin() + __n;
}
Popback和erase函数一样
void pop_back() {
--_M_finish;
destroy(_M_finish);
}
iterator erase(iterator __position) {
if (__position + 1 != end())
copy(__position + 1, _M_finish, __position);
--_M_finish;
destroy(_M_finish);
return __position;
}
Resize函数
当resize大小小于当前Vector中数据大小,删除resize之后的数据
当resize大小大于等于Vector中数据大小,插入end到__new_size之间的数据
void resize(size_type __new_size, const _Tp& __x) {
if (__new_size < size())
erase(begin() + __new_size, end());
else
insert(end(), __new_size - size(), __x);
}
List
数据结构主要有数据class _Tp和指向前后的指针
struct _List_node_base {
_List_node_base* _M_next;
_List_node_base* _M_prev;
};
template <class _Tp>
struct _List_node : public _List_node_base {
_Tp _M_data;
};
List基类
定义默认构造函数,数据_M_node构造默认数据,并将前后指针指向自己。
template <class _Tp, class _Alloc>
class _List_base
{
public:
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_List_base(const allocator_type&) {
_M_node = _M_get_node();
_M_node->_M_next = _M_node;
_M_node->_M_prev = _M_node;
}
~_List_base() {
clear();
_M_put_node(_M_node);
}
void clear();
protected:
//分配内存
typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type;
_List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
protected:
//数据list头指针
_List_node<_Tp>* _M_node;
};
List源码
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class list : protected _List_base<_Tp, _Alloc> {
// requirements:
__STL_CLASS_REQUIRES(_Tp, _Assignable);
typedef _List_base<_Tp, _Alloc> _Base;
protected:
typedef void* _Void_pointer;
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef _List_node<_Tp> _Node;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type;
allocator_type get_allocator() const { return _Base::get_allocator(); }
public:
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> 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<const_iterator,value_type,
const_reference,difference_type>
const_reverse_iterator;
typedef reverse_bidirectional_iterator<iterator,value_type,reference,
difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
protected:
#ifdef __STL_HAS_NAMESPACES
using _Base::_M_node;
using _Base::_M_put_node;
using _Base::_M_get_node;
#endif /* __STL_HAS_NAMESPACES */
protected:
//创建node,当添加数据x时,申请node,并将x数据放入node中的_M_data
_Node* _M_create_node(const _Tp& __x)
{
_Node* __p = _M_get_node();
__STL_TRY {
_Construct(&__p->_M_data, __x);
}
__STL_UNWIND(_M_put_node(__p));
return __p;
}
_Node* _M_create_node()
{
_Node* __p = _M_get_node();
__STL_TRY {
_Construct(&__p->_M_data);
}
__STL_UNWIND(_M_put_node(__p));
return __p;
}
public:
explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {}
//list的begin和end接口分别返回头指针的下一个指针和当前指针,当前指针的头指针中不存放数据,所以end接口返回最后一个数据的下一个地址
iterator begin() { return (_Node*)(_M_node->_M_next); }
const_iterator begin() const { return (_Node*)(_M_node->_M_next); }
iterator end() { return _M_node; }
const_iterator end() const { return _M_node; }
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 _M_node->_M_next == _M_node; }
//list大小为计算开始指针到结束指针之间的距离
size_type size() const {
size_type __result = 0;
distance(begin(), end(), __result);
return __result;
}
size_type max_size() const { return size_type(-1); }
//返回第一个数据和最后一个数据
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(--end()); }
const_reference back() const { return *(--end()); }
void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); }
//list中插入一个数据,假设list中数据排列ABC,在位置B插入数据
//1.创建一个node将x数据放入node
//2.将node的前指针指向A,后指针指向B
//3.A的后指针指向node
//4.B的前指针指向node
iterator insert(iterator __position, const _Tp& __x) {
_Node* __tmp = _M_create_node(__x);
__tmp->_M_next = __position._M_node;
__tmp->_M_prev = __position._M_node->_M_prev;
__position._M_node->_M_prev->_M_next = __tmp;
__position._M_node->_M_prev = __tmp;
return __tmp;
}
iterator insert(iterator __position) { return insert(__position, _Tp()); }
#ifdef __STL_MEMBER_TEMPLATES
// Check whether it's an integral type. If so, it's not an iterator.
template<class _Integer>
void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
__true_type) {
_M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
}
template <class _InputIterator>
void _M_insert_dispatch(iterator __pos,
_InputIterator __first, _InputIterator __last,
__false_type);
template <class _InputIterator>
void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_insert_dispatch(__pos, __first, __last, _Integral());
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator __position, const _Tp* __first, const _Tp* __last);
void insert(iterator __position,
const_iterator __first, const_iterator __last);
#endif /* __STL_MEMBER_TEMPLATES */
void insert(iterator __pos, size_type __n, const _Tp& __x)
{ _M_fill_insert(__pos, __n, __x); }
void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x);
//pushfront和pushback实现为在收尾的位置使用插入接口
void push_front(const _Tp& __x) { insert(begin(), __x); }
void push_front() {insert(begin());}
void push_back(const _Tp& __x) { insert(end(), __x); }
void push_back() {insert(end());}
//删除函数为将删除节点的前后节点相连接
iterator erase(iterator __position) {
_List_node_base* __next_node = __position._M_node->_M_next;
_List_node_base* __prev_node = __position._M_node->_M_prev;
_Node* __n = (_Node*) __position._M_node;
__prev_node->_M_next = __next_node;
__next_node->_M_prev = __prev_node;
_Destroy(&__n->_M_data);
_M_put_node(__n);
return iterator((_Node*) __next_node);
}
iterator erase(iterator __first, iterator __last);
void clear() { _Base::clear(); }
void resize(size_type __new_size, const _Tp& __x);
void resize(size_type __new_size) { this->resize(__new_size, _Tp()); }
popfront和popback函数为删除首位节点
void pop_front() { erase(begin()); }
void pop_back() {
iterator __tmp = end();
erase(--__tmp);
}
list(size_type __n, const _Tp& __value,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ insert(begin(), __n, __value); }
explicit list(size_type __n)
: _Base(allocator_type())
{ insert(begin(), __n, _Tp()); }
#ifdef __STL_MEMBER_TEMPLATES
// We don't need any dispatching tricks here, because insert does all of
// that anyway.
template <class _InputIterator>
list(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ insert(begin(), __first, __last); }
#else /* __STL_MEMBER_TEMPLATES */
list(const _Tp* __first, const _Tp* __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ this->insert(begin(), __first, __last); }
list(const_iterator __first, const_iterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ this->insert(begin(), __first, __last); }
#endif /* __STL_MEMBER_TEMPLATES */
list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator())
{ insert(begin(), __x.begin(), __x.end()); }
~list() { }
list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x);
public:
// assign(), a generalized assignment member function. Two
// versions: one that takes a count, and one that takes a range.
// The range version is a member template, so we dispatch on whether
// or not the type is an integer.
void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
void _M_fill_assign(size_type __n, const _Tp& __val);
#ifdef __STL_MEMBER_TEMPLATES
template <class _InputIterator>
void assign(_InputIterator __first, _InputIterator __last) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_assign_dispatch(__first, __last, _Integral());
}
template <class _Integer>
void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
{ _M_fill_assign((size_type) __n, (_Tp) __val); }
template <class _InputIterator>
void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type);
#endif /* __STL_MEMBER_TEMPLATES */
protected:
//把[first,last)之间的数据放到position之前
void transfer(iterator __position, iterator __first, iterator __last) {
if (__position != __last) {
// Remove [first, last) from its old position.
__last._M_node->_M_prev->_M_next = __position._M_node;
__first._M_node->_M_prev->_M_next = __last._M_node;
__position._M_node->_M_prev->_M_next = __first._M_node;
// Splice [first, last) into its new position.
_List_node_base* __tmp = __position._M_node->_M_prev;
__position._M_node->_M_prev = __last._M_node->_M_prev;
__last._M_node->_M_prev = __first._M_node->_M_prev;
__first._M_node->_M_prev = __tmp;
}
}
public:
//List提供的接合函数是Splice,上述transfer是非公开的函数。splice函数有如下几个版本:
//将list x中的数据放到position之前
void splice(iterator __position, list& __x) {
if (!__x.empty())
this->transfer(__position, __x.begin(), __x.end());
}
//将list中的数据i放到position之前
void splice(iterator __position, list&, iterator __i) {
iterator __j = __i;
++__j;
if (__position == __i || __position == __j) return;
this->transfer(__position, __i, __j);
}
//将list中的[first,last)之间的数据放到position之前
void splice(iterator __position, list&, iterator __first, iterator __last) {
if (__first != __last)
this->transfer(__position, __first, __last);
}
void remove(const _Tp& __value);
void unique();
void merge(list& __x);
void reverse();
void sort();
#ifdef __STL_MEMBER_TEMPLATES
template <class _Predicate> void remove_if(_Predicate);
template <class _BinaryPredicate> void unique(_BinaryPredicate);
template <class _StrictWeakOrdering> void merge(list&, _StrictWeakOrdering);
template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering);
#endif /* __STL_MEMBER_TEMPLATES */
};
template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::insert(iterator __position,
const _Tp* __first, const _Tp* __last)
{
for ( ; __first != __last; ++__first)
insert(__position, *__first);
}
template <class _Tp, class _Alloc>
typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first,
iterator __last)
{
while (__first != __last)
erase(__first++);
return __last;
}
//设置list容器大小为__new_size
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x)
{
iterator __i = begin();
size_type __len = 0;
for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
;
//1. 由于__len < __new_size跳出循环,所以__len == __new_size,这种情况下__i != end(),容器还没有到最后位置,容器大小大于__new_size,需要删除i到end之间的数据
//2.由于__i != end()跳出循环,容器已经到了最后位置,但是__len < __new_size,所以__new_size大于容器大小,需要插入容器end到__new_size之间的数据
if (__len == __new_size)
erase(__i, end());
else // __i == end()
insert(end(), __new_size - __len, __x);
}
//remove函数,删除list中相同的数据
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::remove(const _Tp& __value)
{
iterator __first = begin();
iterator __last = end();
while (__first != __last) {
iterator __next = __first;
++__next;
if (*__first == __value) erase(__first);
__first = __next;
}
}
//unique函数,相邻数据去重
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::unique()
{
iterator __first = begin();
iterator __last = end();
if (__first == __last) return;
iterator __next = __first;
while (++__next != __last) {
if (*__first == *__next)
erase(__next);
else
__first = __next;
__next = __first;
}
}
//merge函数,合并两个列表,列表默认升序排列
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x)
{
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
//1.假设合并B列表到A列表上,默认AB列表均已升序排列,A1,A2,A3,B1,B2,B3,B4
//2.先对比AB列表的首个数据A1和B1,如果B1小于A1,将B1插入到A1前面,并且将B2和A1比较
//3.如果B1大于A1,则将A2和B1比较,知道A列表的数据大于B中的数据,将B插入到A列表
while (__first1 != __last1 && __first2 != __last2)
if (*__first2 < *__first1) {
iterator __next = __first2;
transfer(__first1, __first2, ++__next);
__first2 = __next;
}
else
++__first1;
//当两个列表中的数据有一个对比结束的时候,如果B列表中没有了数据,说明B列表中的数据已经
//升序插入到了A列表,如果B列表中还有数据,因为默认B列表是升序排列,在对比结束后说明剩余//的B列表中的数据比A大,所以直接将B中的数据插入到A列表的后面。
if (__first2 != __last2) transfer(__last1, __first2, __last2);
}
//reverse函数,将列表中的元素反转
inline void __List_base_reverse(_List_node_base* __p)
{
_List_node_base* __tmp = __p;
do {
//将前指针和后指针互换
__STD::swap(__tmp->_M_next, __tmp->_M_prev);
//原本list中的后一个node现在是前一个node,将list中的所有的node前后指针互换
__tmp = __tmp->_M_prev; // Old next node is now prev.
} while (__tmp != __p);
}
template <class _Tp, class _Alloc>
inline void list<_Tp, _Alloc>::reverse()
{
__List_base_reverse(this->_M_node);
}
//按升序排序
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::sort()
{
// Do nothing if the list has length 0 or 1.
if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
list<_Tp, _Alloc> __carry;
list<_Tp, _Alloc> __counter[64];
int __fill = 0;
while (!empty()) {
//取出列表中的第一个节点
__carry.splice(__carry.begin(), *this, begin());
int __i = 0;
//把carry中的数据和counter中的数据合并
while(__i < __fill && !__counter[__i].empty()) {
__counter[__i].merge(__carry);
__carry.swap(__counter[__i++]);
}
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
}
//将counter中的所有元素合并
for (int __i = 1; __i < __fill; ++__i)
__counter[__i].merge(__counter[__i-1]);
swap(__counter[__fill-1]);
}
}
在该排序算法的实现过程中,定义了一个类似于搬运作用的链表carry和具有中转站作用的链表counter,这里首先对counter[i]里面存储数据的规则进行分析;counter[i]里面最多存储数据个数为2的i+1次方,若存储数据超过该数字,则向相邻高位进位,即把counter[i]链表里的内容都合并到counter[i+1]链表。carry负责取出原始链表的头一个数据节点和交换数据中转站作用;源码中的fill表示当前可处理数据的个数为2的fill次方
举例:加入有列表数据9,7,6,5,4
第一次循环
Carry列表取出数据9
While不满足条件,Carry和counter0列表互换
最后的结果为
counter0:9
Carry:1
Fill:1
第二次循环
Carry取出数据7
While满足条件,i小于full,counter0非空
__counter[__i].merge(__carry);
counter0:7,9
__carry.swap(__counter[__i++]);
Carry:7,9
counter0:空
i:1
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
最后结果为
counter0:空
counter1:Carry:7,9
Carry:空
fill:2
第三次循环
Carry取出数据6
While不满足条件:Carry为空
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
最后结果为
counter0:6
counter1:Carry:7,9
Carry:空
fill:2
第四次循环
Carry取出数据5
While满足条件:i小于fill,counter0非空
I等于0
__counter[__i].merge(__carry);
__carry.swap(__counter[__i++]);
counter0:56
Carry:56
counter0:空
i等于1
While满足条件:i小于fill,counter1非空
__counter[__i].merge(__carry);
__carry.swap(__counter[__i++]);
Counter1:5679
Carry:5679
Counter1:空
I等于2
While不满足条件:i等于fill
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
最后结果为
Carry:空
Counter0:空
Counter1:空
Counter2:5679
I:3
第五次循环
Carry取出数据4
While不满足条件:Counter0:空
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
Carry:空
Counter0:4
Counter1:空
Counter2:5679
I:3
List为空跳出循环
for (int __i = 1; __i < __fill; ++__i)
__counter[__i].merge(__counter[__i-1]);
将Counter0数据合并到Counter1,将Counter1数据合并到Counter2
Counter2:4679
swap(__counter[__fill-1]);
将Counter2中内容替换为list自己数据,现排序。
Deque
Deque是双向开口连续性空间,动态将多个连续空间通过指针数组连接在一起,随时可以增加一段新空间。
Deque迭代器
template <class _Tp, class _Ref, class _Ptr>
struct _Deque_iterator {
typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Ptr pointer;
typedef _Ref reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp** _Map_pointer;
typedef _Deque_iterator _Self;
deque的多个连续空间是通过二维指针实现的,查找一个数据需要知道元素空间inde和元素在这个空间的index。迭代器实现自定义自增自减操作符时需要知道当前元素在当前空间是否处于最后或者最前的位置,所以迭代器内部含有三个指针分别指向当前位置,当前空间最前方元素,当前空间最后一个元素的后一个地址和一个指向当前空间地址的二维指针。
//指向当前元素的指针
_Tp* _M_cur;
//指向当前空间第一个元素的指针
_Tp* _M_first;
//指向当前空间最后一个元素的后一个地址的指针
_Tp* _M_last;
//指向空间index的二维指针
_Map_pointer _M_node;
_Deque_iterator(_Tp* __x, _Map_pointer __y)
: _M_cur(__x), _M_first(*__y),
_M_last(*__y + _S_buffer_size()), _M_node(__y) {}
_Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
_Deque_iterator(const iterator& __x)
: _M_cur(__x._M_cur), _M_first(__x._M_first),
_M_last(__x._M_last), _M_node(__x._M_node) {}
reference operator*() const { return *_M_cur; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return _M_cur; }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
difference_type operator-(const _Self& __x) const {
return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
(_M_cur - _M_first) + (__x._M_last - __x._M_cur);
}
//自增操作符,当前指针向后移动,当指针处于最后一个位置的时候,node(二维指针)向后移动,并获取下一个空间的起始地址。
_Self& operator++() {
++_M_cur;
if (_M_cur == _M_last) {
_M_set_node(_M_node + 1);
_M_cur = _M_first;
}
return *this;
}
_Self operator++(int) {
_Self __tmp = *this;
++*this;
return __tmp;
}
//自减操作符,当前指针向前移动,当指针处于最前方位置的时候,node(二维指针)向前移动,并获取上一个空间的末尾地址。
_Self& operator--() {
if (_M_cur == _M_first) {
_M_set_node(_M_node - 1);
_M_cur = _M_last;
}
--_M_cur;
return *this;
}
_Self operator--(int) {
_Self __tmp = *this;
--*this;
return __tmp;
}
_Self& operator+=(difference_type __n)
{
difference_type __offset = __n + (_M_cur - _M_first);
if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
_M_cur += __n;
else {
difference_type __node_offset =
__offset > 0 ? __offset / difference_type(_S_buffer_size())
: -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
_M_set_node(_M_node + __node_offset);
_M_cur = _M_first +
(__offset - __node_offset * difference_type(_S_buffer_size()));
}
return *this;
}
_Self operator+(difference_type __n) const
{
_Self __tmp = *this;
return __tmp += __n;
}
_Self& operator-=(difference_type __n) { return *this += -__n; }
_Self operator-(difference_type __n) const {
_Self __tmp = *this;
return __tmp -= __n;
}
reference operator[](difference_type __n) const { return *(*this + __n); }
bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
bool operator!=(const _Self& __x) const { return !(*this == __x); }
bool operator<(const _Self& __x) const {
return (_M_node == __x._M_node) ?
(_M_cur < __x._M_cur) : (_M_node < __x._M_node);
}
bool operator>(const _Self& __x) const { return __x < *this; }
bool operator<=(const _Self& __x) const { return !(__x < *this); }
bool operator>=(const _Self& __x) const { return !(*this < __x); }
//更新新的node时候,同时更新first和last指针
void _M_set_node(_Map_pointer __new_node) {
_M_node = __new_node;
//first指针为node节点指向的数据
_M_first = *__new_node;
//last指针从first指针开始,根据元素数据的大小向后偏移
//如果数据大小小于512,分配512/元素大小的个数
//如果数据大于512,分配一个
_M_last = _M_first + difference_type(_S_buffer_size());
}
};
// Note: this function is simply a kludge to work around several compilers'
// bugs in handling constant expressions.
inline size_t __deque_buf_size(size_t __size) {
return __size < 512 ? size_t(512 / __size) : size_t(1);
}
Deque Base
template <class _Tp, class _Alloc>
class _Deque_base {
public:
typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Deque_base(const allocator_type&, size_t __num_elements)
: _M_map(0), _M_map_size(0), _M_start(), _M_finish() {
_M_initialize_map(__num_elements);
}
_Deque_base(const allocator_type&)
: _M_map(0), _M_map_size(0), _M_start(), _M_finish() {}
~_Deque_base();
protected:
void _M_initialize_map(size_t);
void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
//二维指针初始大小8,map size
enum { _S_initial_map_size = 8 };
protected:
//当前deque队列的map指针
_Tp** _M_map;
//当前deque队列map大小
size_t _M_map_size;
//当前deque队列start迭代器
iterator _M_start;
//当前deque队列最后数据的下一个地址
iterator _M_finish;
//内存分配器
typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type;
typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type;
_Tp* _M_allocate_node()
{ return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); }
void _M_deallocate_node(_Tp* __p)
{ _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); }
_Tp** _M_allocate_map(size_t __n)
{ return _Map_alloc_type::allocate(__n); }
void _M_deallocate_map(_Tp** __p, size_t __n)
{ _Map_alloc_type::deallocate(__p, __n); }
};
template <class _Tp, class _Alloc>
_Deque_base<_Tp,_Alloc>::~_Deque_base() {
if (_M_map) {
_M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
_M_deallocate_map(_M_map, _M_map_size);
}
}
//初始化map
template <class _Tp, class _Alloc>
void
_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
{
//计算map size,根据_Tp*指向的每个数组个数决定map size大小
//当__num_elements等于50,每个数组存放数据8个,__num_nodes = 7
//需要新建7个map二维指针数组
size_t __num_nodes =
__num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
//在计算的基础上+2,前后各一个,用于添加新数据,最后和默认值8比较取最大值
_M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
//申请内存
_M_map = _M_allocate_map(_M_map_size);
// nstart = _M_map + (9 - 7) / 2 = _M_map + 1
//start指针为_M_map向后偏移一个位置,第一个位置用于拓展数据
_Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
//finish指针指向最后一个数据的下一个地方
_Tp** __nfinish = __nstart + __num_nodes;
//创建node数据,申请内存
__STL_TRY {
_M_create_nodes(__nstart, __nfinish);
}
__STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size),
_M_map = 0, _M_map_size = 0));
//_M_start迭代器设置数据start指向数据
_M_start._M_set_node(__nstart);
//由于finish为空,_M_finish迭代器设置数据为finish向前偏移一个位置
_M_finish._M_set_node(__nfinish - 1);
_M_start._M_cur = _M_start._M_first;
//_M_finish迭代器,_M_finish._M_first为最后一组数据地址+总的元素和每个数组数据取余
//(__num_elements % __deque_buf_size(sizeof(_Tp)))
_M_finish._M_cur = _M_finish._M_first +
__num_elements % __deque_buf_size(sizeof(_Tp));
}
template <class _Tp, class _Alloc>
void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
{
_Tp** __cur;
__STL_TRY {
for (__cur = __nstart; __cur < __nfinish; ++__cur)
*__cur = _M_allocate_node();
}
__STL_UNWIND(_M_destroy_nodes(__nstart, __cur));
}
template <class _Tp, class _Alloc>
void
_Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
{
for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
_M_deallocate_node(*__n);
}
Deque类
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class deque : protected _Deque_base<_Tp, _Alloc> {
// requirements:
__STL_CLASS_REQUIRES(_Tp, _Assignable);
typedef _Deque_base<_Tp, _Alloc> _Base;
public: // Basic types
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type;
allocator_type get_allocator() const { return _Base::get_allocator(); }
public: // Iterators
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator 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_iterator<const_iterator, value_type, const_reference,
difference_type>
const_reverse_iterator;
typedef reverse_iterator<iterator, value_type, reference, difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
protected: // Internal typedefs
//二维数组map指针
typedef pointer* _Map_pointer;
static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
protected:
#ifdef __STL_USE_NAMESPACES
using _Base::_M_initialize_map;
using _Base::_M_create_nodes;
using _Base::_M_destroy_nodes;
using _Base::_M_allocate_node;
using _Base::_M_deallocate_node;
using _Base::_M_allocate_map;
using _Base::_M_deallocate_map;
using _Base::_M_map;
using _Base::_M_map_size;
using _Base::_M_start;
using _Base::_M_finish;
#endif /* __STL_USE_NAMESPACES */
public: // Basic accessors
//begin end函数直接返回start,finish迭代器
iterator begin() { return _M_start; }
iterator end() { return _M_finish; }
const_iterator begin() const { return _M_start; }
const_iterator end() const { return _M_finish; }
reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
reverse_iterator rend() { return reverse_iterator(_M_start); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(_M_finish); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(_M_start); }
reference operator[](size_type __n)
{ return _M_start[difference_type(__n)]; }
const_reference operator[](size_type __n) const
{ return _M_start[difference_type(__n)]; }
#ifdef __STL_THROW_RANGE_ERRORS
void _M_range_check(size_type __n) const {
if (__n >= this->size())
__stl_throw_range_error("deque");
}
reference at(size_type __n)
{ _M_range_check(__n); return (*this)[__n]; }
const_reference at(size_type __n) const
{ _M_range_check(__n); return (*this)[__n]; }
#endif /* __STL_THROW_RANGE_ERRORS */
//front back函数返回对应迭代器
reference front() { return *_M_start; }
reference back() {
iterator __tmp = _M_finish;
--__tmp;
return *__tmp;
}
const_reference front() const { return *_M_start; }
const_reference back() const {
const_iterator __tmp = _M_finish;
--__tmp;
return *__tmp;
}
size_type size() const { return _M_finish - _M_start; }
size_type max_size() const { return size_type(-1); }
bool empty() const { return _M_finish == _M_start; }
deque& operator= (const deque& __x) {
const size_type __len = size();
if (&__x != this) {
if (__len >= __x.size())
erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
else {
const_iterator __mid = __x.begin() + difference_type(__len);
copy(__x.begin(), __mid, _M_start);
insert(_M_finish, __mid, __x.end());
}
}
return *this;
}
void swap(deque& __x) {
__STD::swap(_M_start, __x._M_start);
__STD::swap(_M_finish, __x._M_finish);
__STD::swap(_M_map, __x._M_map);
__STD::swap(_M_map_size, __x._M_map_size);
}
public:
// assign(), a generalized assignment member function. Two
// versions: one that takes a count, and one that takes a range.
// The range version is a member template, so we dispatch on whether
// or not the type is an integer.
//deque填充n大小数据为val
void _M_fill_assign(size_type __n, const _Tp& __val) {
if (__n > size()) {
fill(begin(), end(), __val);
insert(end(), __n - size(), __val);
}
else {
erase(begin() + __n, end());
fill(begin(), end(), __val);
}
}
//assin函数
void assign(size_type __n, const _Tp& __val) {
_M_fill_assign(__n, __val);
}
public: // push_* and pop_*
//pushback函数,deque尾部添加数据
void push_back(const value_type& __t) {
//判断是否含有空间
if (_M_finish._M_cur != _M_finish._M_last - 1) {
//构造数据t在指针_M_finish._M_cur位置
construct(_M_finish._M_cur, __t);
//指针偏移
++_M_finish._M_cur;
}
Else
//没有空间情况下添加数据t
_M_push_back_aux(__t);
}
void push_back() {
if (_M_finish._M_cur != _M_finish._M_last - 1) {
construct(_M_finish._M_cur);
++_M_finish._M_cur;
}
else
_M_push_back_aux();
}
//pushfront函数,头部添加数据
void push_front(const value_type& __t) {
//判断是否还有空间
if (_M_start._M_cur != _M_start._M_first) {
//构造数据
construct(_M_start._M_cur - 1, __t);
//指针偏移
--_M_start._M_cur;
}
else
_M_push_front_aux(__t);
}
void push_front() {
if (_M_start._M_cur != _M_start._M_first) {
construct(_M_start._M_cur - 1);
--_M_start._M_cur;
}
else
_M_push_front_aux();
}
//popback函数,销毁尾部数据
void pop_back() {
//当前数据是否此块第一个数据
if (_M_finish._M_cur != _M_finish._M_first) {
//如果不是,销毁此数据?
--_M_finish._M_cur;
destroy(_M_finish._M_cur);
}
Else
//如果是,空间前移
_M_pop_back_aux();
}
//popfront函数,销毁头部数据
void pop_front() {
//是否处于此块最后一个位置
if (_M_start._M_cur != _M_start._M_last - 1) {
//如果不是,销毁此数据,指针向后移
destroy(_M_start._M_cur);
++_M_start._M_cur;
}
else
//如果处于最后一个位置,空间后移
_M_pop_front_aux();
}
public: // Insert
//insert函数,插入数据
iterator insert(iterator position, const value_type& __x) {
//如果position在deque最前方
if (position._M_cur == _M_start._M_cur) {
push_front(__x);
return _M_start;
}
//如果position在deque最后方
else if (position._M_cur == _M_finish._M_cur) {
push_back(__x);
iterator __tmp = _M_finish;
--__tmp;
return __tmp;
}
else {
//如果position在deque中间
return _M_insert_aux(position, __x);
}
}
void resize(size_type __new_size, const value_type& __x) {
const size_type __len = size();
if (__new_size < __len)
erase(_M_start + __new_size, _M_finish);
else
insert(_M_finish, __new_size - __len, __x);
}
void resize(size_type new_size) { resize(new_size, value_type()); }
public: // Erase
iterator erase(iterator __pos) {
iterator __next = __pos;
++__next;
difference_type __index = __pos - _M_start;
if (size_type(__index) < (this->size() >> 1)) {
copy_backward(_M_start, __pos, __next);
pop_front();
}
else {
copy(__next, _M_finish, __pos);
pop_back();
}
return _M_start + __index;
}
void clear();
protected: // Internal push_* and pop_*
void _M_push_back_aux(const value_type&);
void _M_push_back_aux();
void _M_push_front_aux(const value_type&);
void _M_push_front_aux();
void _M_pop_back_aux();
void _M_pop_front_aux();
protected: // Internal insert functions
iterator _M_insert_aux(iterator __pos, const value_type& __x);
};
template <class _Tp, class _Alloc>
typename deque<_Tp,_Alloc>::iterator
deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
{
if (__first == _M_start && __last == _M_finish) {
clear();
return _M_finish;
}
else {
difference_type __n = __last - __first;
difference_type __elems_before = __first - _M_start;
if (__elems_before < difference_type((this->size() - __n) / 2)) {
copy_backward(_M_start, __first, __last);
iterator __new_start = _M_start + __n;
destroy(_M_start, __new_start);
_M_destroy_nodes(__new_start._M_node, _M_start._M_node);
_M_start = __new_start;
}
else {
copy(__last, _M_finish, __first);
iterator __new_finish = _M_finish - __n;
destroy(__new_finish, _M_finish);
_M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
_M_finish = __new_finish;
}
return _M_start + __elems_before;
}
}
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::clear()
{
for (_Map_pointer __node = _M_start._M_node + 1;
__node < _M_finish._M_node;
++__node) {
destroy(*__node, *__node + _S_buffer_size());
_M_deallocate_node(*__node);
}
if (_M_start._M_node != _M_finish._M_node) {
destroy(_M_start._M_cur, _M_start._M_last);
destroy(_M_finish._M_first, _M_finish._M_cur);
_M_deallocate_node(_M_finish._M_first);
}
else
destroy(_M_start._M_cur, _M_finish._M_cur);
_M_finish = _M_start;
}
#ifdef __STL_MEMBER_TEMPLATES
// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
{
value_type __t_copy = __t;
_M_reserve_map_at_back();
*(_M_finish._M_node + 1) = _M_allocate_node();
__STL_TRY {
construct(_M_finish._M_cur, __t_copy);
_M_finish._M_set_node(_M_finish._M_node + 1);
_M_finish._M_cur = _M_finish._M_first;
}
__STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
}
// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_push_back_aux()
{
_M_reserve_map_at_back();
*(_M_finish._M_node + 1) = _M_allocate_node();
__STL_TRY {
construct(_M_finish._M_cur);
_M_finish._M_set_node(_M_finish._M_node + 1);
_M_finish._M_cur = _M_finish._M_first;
}
__STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
}
// Called only if _M_start._M_cur == _M_start._M_first.
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
{
value_type __t_copy = __t;
_M_reserve_map_at_front();
*(_M_start._M_node - 1) = _M_allocate_node();
__STL_TRY {
_M_start._M_set_node(_M_start._M_node - 1);
_M_start._M_cur = _M_start._M_last - 1;
construct(_M_start._M_cur, __t_copy);
}
__STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
}
// Called only if _M_start._M_cur == _M_start._M_first.
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_push_front_aux()
{
_M_reserve_map_at_front();
*(_M_start._M_node - 1) = _M_allocate_node();
__STL_TRY {
_M_start._M_set_node(_M_start._M_node - 1);
_M_start._M_cur = _M_start._M_last - 1;
construct(_M_start._M_cur);
}
__STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
}
// Called only if _M_finish._M_cur == _M_finish._M_first.
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_pop_back_aux()
{
_M_deallocate_node(_M_finish._M_first);
_M_finish._M_set_node(_M_finish._M_node - 1);
_M_finish._M_cur = _M_finish._M_last - 1;
destroy(_M_finish._M_cur);
}
// Called only if _M_start._M_cur == _M_start._M_last - 1. Note that
// if the deque has at least one element (a precondition for this member
// function), and if _M_start._M_cur == _M_start._M_last, then the deque
// must have at least two nodes.
template <class _Tp, class _Alloc>
void deque<_Tp,_Alloc>::_M_pop_front_aux()
{
destroy(_M_start._M_cur);
_M_deallocate_node(_M_start._M_first);
_M_start._M_set_node(_M_start._M_node + 1);
_M_start._M_cur = _M_start._M_first;
}
template <class _Tp, class _Alloc>
typename deque<_Tp, _Alloc>::iterator
deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
{
difference_type __index = __pos - _M_start;
value_type __x_copy = __x;
if (size_type(__index) < this->size() / 2) {
push_front(front());
iterator __front1 = _M_start;
++__front1;
iterator __front2 = __front1;
++__front2;
__pos = _M_start + __index;
iterator __pos1 = __pos;
++__pos1;
copy(__front2, __pos1, __front1);
}
else {
push_back(back());
iterator __back1 = _M_finish;
--__back1;
iterator __back2 = __back1;
--__back2;
__pos = _M_start + __index;
copy_backward(__pos, __back2, __back1);
}
*__pos = __x_copy;
return __pos;
}
适配器容器
Stack
堆栈是一个线性表,插入和删除只在表的一端进行。这一端称为栈顶,另一端称为栈底。堆栈的元素插入称为入栈,元素的删除称为出栈。由于元素的入栈和出栈总在栈顶进行,因此,堆栈是一个后进先出表。
Stl的堆栈是通过现有的序列式容器来实现的,默认使用双端列deque的数据结构,当然,也可以采用其他线性结构vector或list。只要提供堆栈的入栈出栈,栈顶元素访问,判断是否为空的操作即可。由于堆栈的底层使用的是其他容器,因此,堆栈可以看做是一种适配器,将一种容器转换为另一种容器。
Stack源码
默认使用deque
template <class _Tp,
class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >
class stack;
template <class _Tp, class _Sequence>
class stack {
// requirements:
__STL_CLASS_REQUIRES(_Tp, _Assignable);
__STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);
typedef typename _Sequence::value_type _Sequence_value_type;
__STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);
#ifdef __STL_MEMBER_TEMPLATES
template <class _Tp1, class _Seq1>
friend bool operator== (const stack<_Tp1, _Seq1>&,
const stack<_Tp1, _Seq1>&);
template <class _Tp1, class _Seq1>
friend bool operator< (const stack<_Tp1, _Seq1>&,
const stack<_Tp1, _Seq1>&);
#else /* __STL_MEMBER_TEMPLATES */
friend bool __STD_QUALIFIER
operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
friend bool __STD_QUALIFIER
operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
#endif /* __STL_MEMBER_TEMPLATES */
public:
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
protected:
//定义序列式容器c
_Sequence c;
public:
stack() : c() {}
explicit stack(const _Sequence& __s) : c(__s) {}
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
//栈顶元素为容器中最后一个数据,实现stack
reference top() { return c.back(); }
const_reference top() const { return c.back(); }
//添加元素放入容器最后
void push(const value_type& __x) { c.push_back(__x); }
//pop函数实现删除最后数据
void pop() { c.pop_back(); }
};
Queue
Queue具有先进先出的数据结构,仅仅支持新增元素,移除元素,从最低端加入元素,区最顶端元素。
//默认使用deque容器
template <class _Tp,
class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >
class queue;
//queue类代码
template <class _Tp, class _Sequence>
class queue {
// requirements:
__STL_CLASS_REQUIRES(_Tp, _Assignable);
__STL_CLASS_REQUIRES(_Sequence, _FrontInsertionSequence);
__STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);
typedef typename _Sequence::value_type _Sequence_value_type;
__STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);
#ifdef __STL_MEMBER_TEMPLATES
template <class _Tp1, class _Seq1>
friend bool operator== (const queue<_Tp1, _Seq1>&,
const queue<_Tp1, _Seq1>&);
template <class _Tp1, class _Seq1>
friend bool operator< (const queue<_Tp1, _Seq1>&,
const queue<_Tp1, _Seq1>&);
#else /* __STL_MEMBER_TEMPLATES */
friend bool __STD_QUALIFIER
operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&);
friend bool __STD_QUALIFIER
operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&);
#endif /* __STL_MEMBER_TEMPLATES */
public:
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
protected:
//定义容器c
_Sequence c;
public:
queue() : c() {}
explicit queue(const _Sequence& __c) : c(__c) {}
//判断容器c是否为空
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
//front返回最先加入的元素
reference front() { return c.front(); }
const_reference front() const { return c.front(); }
//back返回最末尾元素
reference back() { return c.back(); }
const_reference back() const { return c.back(); }
//push添加元素到末尾
void push(const value_type& __x) { c.push_back(__x); }
//pop删除最顶端元素
void pop() { c.pop_front(); }
};
Priority_queue
优先队列,队首元素一定是当前队列中优先级最高的一个,在优先队列中没有front函数与back函数,只能同过投票函数访问队首元素,也可称为栈顶元素,也就是优先级最高的元素,基本操作有pop,push,size,top。
Priority_queue默认为大顶堆,即堆顶元素为堆中最大元素,设置小顶堆需要增加两个参数
Priority_queue
priority_queue< int, vector<int>, greater<int> > q; // 小顶堆
priority_queue< int, vector<int>, less<int> > q; // 大顶堆
如果需要对结构体的优先级设置,有两种方法:
方式一:重载运算符‘<’
方式二:把重载的函数写在结构体外
//方式一(比较函数写在结构体外面):
struct student{
std::string name;
int score;
student(std::string _name = "", int _score = 0):name(_name), score(_score) {}
};
struct cmp{
bool operator() (const student& a, const student& b )
{
return a.score > b.score;
}
};
//方式二(重载操作符):
struct Fruit{
std::string name;
double price;
Fruit(std::string _name = "", double _price = 0):name(_name), price(_price) {}
friend bool operator < (const Fruit left, const Fruit right ){
return left.price > right.price;
}
};
Priority_queue
//默认vector容器,compare比较函数
template <class _Tp,
class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>),
class _Compare
__STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) >
//实现代码
class priority_queue {
// requirements:
__STL_CLASS_REQUIRES(_Tp, _Assignable);
__STL_CLASS_REQUIRES(_Sequence, _Sequence);
__STL_CLASS_REQUIRES(_Sequence, _RandomAccessContainer);
typedef typename _Sequence::value_type _Sequence_value_type;
__STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);
__STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);
public:
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
protected:
//定义容器c
_Sequence c;
//比较函数comp
_Compare comp;
public:
priority_queue() : c() {}
explicit priority_queue(const _Compare& __x) : c(), comp(__x) {}
priority_queue(const _Compare& __x, const _Sequence& __s)
: c(__s), comp(__x)
{ make_heap(c.begin(), c.end(), comp); }
#ifdef __STL_MEMBER_TEMPLATES
template <class _InputIterator>
priority_queue(_InputIterator __first, _InputIterator __last)
: c(__first, __last) { make_heap(c.begin(), c.end(), comp); }
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,
const _Compare& __x, const _Sequence& __s)
: c(__s), comp(__x)
{
c.insert(c.end(), __first, __last);
make_heap(c.begin(), c.end(), comp);
}
#else /* __STL_MEMBER_TEMPLATES */
priority_queue(const value_type* __first, const value_type* __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,
const _Compare& __x, const _Sequence& __c)
: c(__c), comp(__x)
{
c.insert(c.end(), __first, __last);
make_heap(c.begin(), c.end(), comp);
}
#endif /* __STL_MEMBER_TEMPLATES */
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
//top函数,返回最顶端元素,优先级最高元素
const_reference top() const { return c.front(); }
//push函数,添加元素
void push(const value_type& __x) {
__STL_TRY {
c.push_back(__x);
//排序
push_heap(c.begin(), c.end(), comp);
}
__STL_UNWIND(c.clear());
}
//pop函数,删除元素
void pop() {
__STL_TRY {
//排序
pop_heap(c.begin(), c.end(), comp);
//删除堆顶元素?
c.pop_back();
}
__STL_UNWIND(c.clear());
}
};