简体   繁体   English

如何在c ++ stl中实现双端队列

[英]How is deque implemented in c++ stl

我只是想知道如何实现双端队列,以及在该实现中如何提供诸如push_front和random access operator之类的基本操作

I just wanted to know how deque is implemented 我只是想知道如何执行双端队列

It's always a good to have an excuse for doing ASCII art: 借口做ASCII艺术总是很好的:

+-------------------------------------------------------------+                       
| std::deque<int>                                             |                       
|                                                             |                       
|  subarrays:                                                 |                       
| +---------------------------------------------------------+ |                       
| |           |           |           |         |           | |                       
| | int(*)[8] | int(*)[8] | int(*)[8] |int(*)[8]|int(*)[8]  | |                       
| |           |           |           |         |           | |                       
| +---------------------------------------------------------+ |                       
|                        /            \                       |                       
|                       /              \                      |                       
|                      /                \                     |                       
|                     /                  \                    |                       
|                    /                    \                   |                       
|                   /                      \                  |                       
|                  /                        \                 |                       
|                 /                          \                |                       
|                -                            -               |                       
|               +------------------------------+              |                       
|               | ?, ?, 42, 43, 50, ?, ?, ?, ? |              |                       
|               +------------------------------+              |                       
|                                                             |
| additional state:                                           |                       
|                                                             |                       
| - pointer to begin of the subarrays                         |                       
| - current capacity and size                                 |                       
| - pointer to current begin and end                          |                       
+-------------------------------------------------------------+                       

how are the basic operations like push_front and random access operator are provided in that implementation? 该实现中如何提供诸如push_front和random access operator之类的基本操作?

First, std::deque::push_front , from libcxx: 首先,来自libcxx的std::deque::push_front

template <class _Tp, class _Allocator>
void
deque<_Tp, _Allocator>::push_front(const value_type& __v)
{
    allocator_type& __a = __base::__alloc();
    if (__front_spare() == 0)
        __add_front_capacity();
    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
    --__base::__start_;
    ++__base::size();
}

This obviously checks whether the memory already allocated at the front can hold an additional element. 显然,这检查了已经分配在前端的内存是否可以容纳其他元素。 If not, it allocates. 如果没有,它将分配。 Then, the main work is shifted to the iterator: _VSTD::addressof(*--__base::begin()) goes one location before the current front element of the container, and this address is passed to the allocator to construct a new element in place by copying v (the default allocator will definitely do a placement- new ). 然后,主要工作转移到迭代器: _VSTD::addressof(*--__base::begin())在容器的当前前元素之前_VSTD::addressof(*--__base::begin())一个位置,并将此地址传递给分配器以构造一个新的元素通过复制v到位(默认分配器肯定会进行new放置)。

Now random access. 现在随机访问。 Again from libcxx, std::deque::operator[] (the non- const version) is 同样从libcxx开始, std::deque::operator[] (非const版本)是

template <class _Tp, class _Allocator>
inline
typename deque<_Tp, _Allocator>::reference
deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
{
    size_type __p = __base::__start_ + __i;
    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
}

This pretty much computes an index relative to some start index, and then determines the subarray and the index relative to the start of the subarray. 这几乎可以计算相对于某个起始索引的索引,然后确定子数组和相对于子数组起始的索引。 __base::__block_size should be the size of one subarray here. __base::__block_size应该是一个子__base::__block_size的大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM