STD DEQUE

Deque

std::deque(双端队列)时一种支持索引的序列容器,在双端允许快速插入和删除。另外,在双端的插入和删除不会使剩余元素的指针和引用非法。

相较于std::vector,deque的元素不是连续存储的:典型的实现使用单独分配的固定大小的数组序列,用额外的记录记录数组单元的序列。这意味着deque的索引访问必须执行两次指针解引用。

deque 的存储空间会自动依据需求去拓展和收缩。deque的拓展较vector更加的cheaper,因为不会将存在的元素进行拷贝到一个新的存储空间。另一方面,deque通常有很大的最小内存成本;仅有一个元素的deque对象需要分配整个内在数组。

deque上的常规操作的复杂度(效率)如下:

  • 随机访问-constant O(1)
  • 首位插入和删除-constant O(1)
  • 元素的插入和删除-线性 O(n)

std::deque 满足 Container, AllocatorAwareContainer, SequeuceContainer 和 ReversibleContainer

指导思想

典型实现用单独分配的固定大小数组的序列。

关于buffer

inline size_t __deque_buf_size(size_t __size) {
	return __size < 512 ? size_t(512 / __size) : size_t(1);
}
  • 固定大小(512字节)的buffer能容纳的最大目标类型数量。
  • buffer即为典型实现用单独分配的固定大小数组。

迭代器

  • 迭代器类型为随机访问迭代器,实现[n]+n
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;

	_Tp* _M_cur;		// 当前指向的元素
	_Tp* _M_first;		// 本数组的第一个元素
	_Tp* _M_last;		// 本数组的最后一个元素
	_Map_point _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_cur(0), _M_frist(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; }
pointer operator->() const { return _M_cur; }

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);
}

_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;
}

_Self& operator--() {
	if(_M_cur == _M_start) {
		_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 < diffence_type(_S_buffer_size()))
		_N_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;
}
}

分配器

template <class _Tp, class _Alloc, bool __is_static>
class _Deque_alloc_base {
public:
	typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
	// 节点分配器处理的类型为_Tp
	allocator_type get_allocator() const { return _M_node_allocator; }
	_Deque_alloc_base(const allocator_type& __a)
		: _M_node_allocator(__a), _M_map_allocator(__a), _M_map(0), _M_map_size(0) {
	}
protected:
	typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type _Map_allocator_type;
	// 映射分配器处理的类型为_Tp*
	allocator_type _M_node_allocator;
	_Map_allocator_type _M_map_allocator;
	
	// 分配__deque_buf_size(sizeof(_Tp))个Tp的内存, 并返回起始地址
	_Tp* _M_allocate_node() {
		return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
	}
	// 释放__deque_buf_size(sizeof(_Tp))个Tp的内存, 起始地址为__p
	void _M_deallocate_node(_Tp* __p) {
		_M_node_allocator.dellocate(__p, __deque_buf_size(sizeof(_Tp)))
	}
	// 分配n个字节的内存空间以存储_Tp*,返回起始地址_Tp**
	_Tp** _M_allocate_map(size_t __n) {
		return _M_map_allocator.allocate(__n);
	}	
	// 释放n个Tp*的内存, 起始地址为__p
	void _M_deallocate_map(_Tp** __p, size_t __n) {
		_M_map_allocator.deallocate(__p, __n);
	}
	
	_Tp** _M_map;			// 映射表起始地址
	size_t _M_map_size;		// 映射表大小
};

静态版本,使用静态函数实现内存分配和回收。

template <class _Tp, class _Alloc>
class _Deque_alloc_base<_Tp, _Alloc, true> {
public:
	typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
	allocator_type get_allocator() const { return allocator_type(); }
	
	_Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
protected:
	typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
	typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;

		// 分配__deque_buf_size(sizeof(_Tp))个Tp的内存, 并返回起始地址
	_Tp* _M_allocate_node() {
		return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
	}
	// 释放__deque_buf_size(sizeof(_Tp))个Tp的内存, 起始地址为__p
	void _M_deallocate_node(_Tp* __p) {
		_Node_alloc_type::dellocate(__p, __deque_buf_size(sizeof(_Tp)))
	}
	// 分配n个字节的内存空间以存储_Tp*,返回起始地址_Tp**
	_Tp** _M_allocate_map(size_t __n) {
		return _Map_alloc_type::allocate(__n);
	}	
	// 释放n个Tp*的内存, 起始地址为__p
	void _M_deallocate_map(_Tp** __p, size_t __n) {
		_Map_alloc_type::deallocate(__p, __n);
	}  
}

Deque

template <class _Tp, class _Alloc>
class _Deque_base : public _Deque_alloc_base<_Tp, _Alloc, 
											_Alloc_traits<_Tp, _Alloc>::_S_instanceless> {
public:
	typedef _Deque_alloc_base<_Tp, _Alloc, 
							_Alloc_traits<_Tp, _Alloc>::_S_instanceless> 
			_Base;
	typedef typename _Base::allocator_type allocator_type;
	typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
	typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
	
	_Deque_base(const allocator_type& __a, size_t __num_elements)
		: _Base(__a), _M_start(), _M_finish() {
		_M_initialize_map(__num_elements);
	}
	_Deque_base(const allocator_type& __a) : _Base(__a), _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);
	enum { _S_initial_map_size = 8 };
protected:
	iterator _M_start;
	iterator _M_finish;
}

定义

template class<class _Tp, class _Alloc>
_Deque_base<_Tp, _Alloc>::~Deque_base() {
	if(_M_map) {
		// 释放所有迭代器指向的节点(buffer)
		_M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
		// 释放映射表所占据的连续内存(数组)
		_M_deallocate_map(_M_map, _M_map_size);
	}
}
template<class _Tp, class _Alloc>
void _Deque_base<_Tp, _Alloc>::_M_initialize_map(size_t __num_elements) {
	size_t __num_nodes = 
		__num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
	_M_map_size = max((size_t)_S_initial_map_size, __num_nodes + 2);
	_M_map = _M_allocate_map(_M_map_size);
	// 映射首尾至少各留出一个节点指针用于未来的增长,没有分配元素
	_Tp** _nstart = _M_map + (_M_map + (_M_map_size - __num_nodes))/2
	_Tp** __nfinish = __nstart + __num_nodes;
	__STL_TRY {
		_M_create_nodes(__nstart, __nfinish);
	}
	__STL_UNWIND((_M_Deallocate_map(_M_map, _M_map_size), 
				  _M_map = 0, _M_mmap_size = 0));
	// 迭代器绑定节点
	_M_start._M_set_node(__nstart);
	_M_finish._M_set_node(_nfinish-1);
	_M_start._M_cur = _M_start._M_first;
	_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_destory_nodes(_Tp** __nstart, _Tp** __nfinish) {
	for(_Tp** __n = __nstart; __n < __nfinish; ++__n) {
		_M_deallocate_node(*__n);
	}
}
template <class _Tp, class _Alloc>
class deque : protected _Deque_base<_Tp, _Alloc> {
	typedef _Deque_base<_Tp, _Alloc> _Base;
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 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 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
	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

protected:
	typedef pointer* _Map_pointer; // value_type**
	static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } // 一个buffer(节点)能存储多少个对象(元素)。
protected:
#ifdef __STL_USE_NAMESPACES
	using _Base::_M_initialize_map;  // 初始化Map需要的内存,为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; // 为Map分配内存
	using _Base::_M_deallocate_map; // 释放Map内存

	using _Base::_M_map;
	using _Base::_M_map_size;
	using _Base::_M_start;
	using _Base::_M_finish;
#endif

public:
	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

reference front() { return *_M_start; }
reference back() {
	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; }

publicexplicit deque(const allocator_type& __a = allocator_type())
	: _Base(__a, 0) {}

deque(const deque& __x) : _Base(_x.get_allocator(), __x.size()) {
	uninitialized_copy(__x.begin(), __x.end(), _M_start);
}

deque(size_type __n, const value_type& __value, 
	  const allocator_type& __a = allocator_type()) : _Base(__a, __n) 
	  { _M_fill_initialize(__value); }
explicit deque(size_type __n) : _Base(allocator_type(), __n) {
	_M_fill_initialize(value_type());
}

#ifdef __STL_MEMBER_TEMPLATES
template <class _InputIterator>
deque(_InputIterator __first, _InputIterator __last, 
	  const allocator_type& __a = allocator_type()) : Base(__a) {
	typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
	_M_initialize_dispatch(__first, __last, _Integral());
}

template <class _Integer>
void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
	_M_initialize_map(__n);
	_M_fill_initialize(__x);
}

template <class _InputIter>
void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); }

#else

deque(const value_type* __first, const value_type* __last, 
		const allocator_type& __a = allocator_type())
		: _Base(__a, __last - __first) {
	uninitialize_copy(__first, __last, _M_start);
}

deque(const_iterator __first, const_iterator __last,
	const allocator_type& __a = allocator_type()) 
    : _Base(__a, __last - __first)
{ uninitialized_copy(__first, __last, _M_start); }

#endif

~deque() { destory(_M_start, _M_finish); } // 存储元素主动调用析构函数

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:
	void assign(size_type __n, const _Tp& __val) {
		_M_fill_assign(__n, __val);
	}
	
	void _M_fill_assign(size_tyoe __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);
		}
	}

push_back

public:
	// _M_finish._M_last 本buffer结束标记,不能赋值。
	void push_back(const value_type& __t) {
		if(_M_finish._M_cur != _M_finish._M_last - 1) {
			construct(_M_finish._M_cur, __t);
			++_M_finish._M_cur;
		}
		else
			_M_push_back_aux(__t);
	}
	
	void _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)));
	}
	
	void _M_reserve_map_at_back(size_type __nodes_to_add = 1) {
		if(__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map)) {
			_M_reallocate_map(__nodes_to_add, false);
		}
	}

	void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) {
		size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
		size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
		
		_Map_pointer __new_nstart;
		if(_M_map_size > 2*__new_num_nodes) {
			__new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
							+ (__add_at_front ? __nodes_to_add : 0);
			if(__new_nstart < _M_start._M_node)
				copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
			else
				copy_backward(_M_start._M_node, _M_finish._M_node + 1,
							  __new_nstart + __old_num_nodes);
		}
		else {
			size_type __new_map_size = 
				_M_map_size + max(_M_map_size, __nodes_to_add) + 2;
			
			_Map_pointer __new_map = _M_allocate_map(__new_map_size);
			__new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
							+ (__add_at_front ? __nodes_to_add : 0);
			copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
			_M_deallocate_map(_M_map, _M_map_size);
			
			_M_map = __new_map;
			_M_map_size = __new_map_size;
		}
		
		_M_start._M_set_node(__new_nstart);
		_M_finish._M_set_node(__new_nstart + old_num_nodes - 1);
	}

	void push_back() {
		if(_M_finish._M_cur != _M_finish._M_last - 1) {
			construct(_M_start._M_cur);
			++_M_start._M_cur;
		}
		else
			_M_push_back_aux(__t);
	}

push_front

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 _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)));
}

void push_front() {
	if(_M_start._M_cur != _M_start.first) {
		construct(_M_start._M_cur - 1);
		--_M_start._M_cur;
	}
	else 
		_M_push_front_aux();
}

pop_back

void pop_back() {
	if(_M_finish._M_cur != _M_finish._M_first) {
		--_M_finish._M_cur;
		destory(_M_finish._M_cur);
	}
	else 
		_M_pop_back_aux();
}

void _M_pop_back_aux() {
	_M_deallocate_node(_M_finish._M_first);
	_M_finish._M_set_node(_M_finish._M_mode - 1);
	_M_finish._M_cur = _M_finish._M_last - 1;
	destroy(_M_finish._M_cur);
}

pop_front

void pop_front() {
	if(_M_start._M_cur != _M_start._M_last - 1) {
		destory(_M_start._M_cur);
		--_M_start._M_cur--;
	}
	else
		_M_pop_front_aux();
}

void _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;
}

Insert

iterator insert(iterator position, const value_type& __x) {
	if(position._M_cur == _M_start._M_cur) {
		push_front(__x);
		return _M_start;
	}
	else if(position._M_cur == _M_finish._M_cur) {
		push_back(__x);
		iterator __tmp = _M_finish;
		--__tmp;
		return __tmp;
	}
	else {
		return _M_insert_aux(position, __x);
	}
}

iterator _M_insert_aux(iterator position, 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;
		copybackward(pos, __back2, __back1);
	}
	*__pos = __x_copy;
	return __pos;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值