std::deque

 

std::deque是区别于vector和list的一种有序容器,可以像vector一样高效的取下标,却别于vector, deque可以高效的前插入,自我成长也比vector要高效些。但deque的迭代器操作是没有vector高效的,对deque排序也是异常复杂的,deque的数据结构如下图所示。

 

 

简单的代码实现:

#include <algorithm>
// deque是一个中控器(map)管理多个节点,该函数返回一个节点node存放元素的个数
inline size_t deque_buf_size(size_t __size) 
{
    return __size < 512 ? size_t(512 / __size) : size_t(1);
}

template <typename Tp, typename Ref, typename Ptr>
struct Deque_iterator 
{
    typedef Deque_iterator<Tp, Tp&, Tp*>             iterator;
    static size_t s_buffer_size() { return deque_buf_size(sizeof(Tp)); }

    typedef Tp value_type;
    typedef Ptr pointer;
    typedef Ref reference;
    typedef size_t size_type;
    typedef Tp** Map_pointer;  // map是一个二维指针,指针数组里存放每一个buf的首地址
    typedef Deque_iterator Self;

    Tp*                m_cur;   // 指向当前元素的指针
    Tp*                m_first; // 指向所在buf的首地址
    Tp*                m_last;     // 指向所在buf的结尾,所以不指向实际元素
    Tp**            m_node;     // map里的节点,指向所在buf首地址

    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; }
    pointer operator->() const { return m_cur; }
    size_t operator-(const Self& x) const 
    {
        return 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_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+=(int n)
    {
        int offset = n + (m_cur - m_first);
        if (offset >= 0 && offset < (s_buffer_size()))
        {  // 如果在单个buf里,直接偏移就可
            m_cur += n;
        }
        else 
        {
            int node_offset = offset > 0 ? offset / s_buffer_size()
                : -(-offset - 1) / s_buffer_size() - 1;
            m_set_node(m_node + node_offset); // 切换节点,m_first也变掉了
            m_cur = m_first + (offset - node_offset * s_buffer_size());
        }
        return *this;
    }

    Self operator+(int n) const
    {
        Self tmp = *this;
        return tmp += n;
    }

    Self& operator-=(int __n) { return *this += -__n; }

    Self operator-(int __n) const {
        Self tmp = *this;
        return tmp -= __n;
    }

    reference operator[](size_t 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); }

    // 设置节点
    void m_set_node(Tp** new_node) 
    {
        m_node = new_node;
        m_first = *new_node;
        m_last = m_first + s_buffer_size();
    }
};

template <typename Tp>
class Deque_base 
{
public:
    typedef Deque_iterator<Tp, Tp&, Tp*>             iterator;

    Deque_base(size_t num_elements) : m_map(0), m_map_size(0), m_start(), m_finish()
    {
        m_initialize_map(num_elements);
    }
    ~Deque_base()
    {
        if (m_map)
        {
            for (Tp** node = m_start.m_node; node <= m_finish.m_node; ++node)
            {  
                printf("%p\n",*node);
                // 释放每一个buf
                free(*node);
                *node = 0;
            }
            printf("\n");
            free(m_map); // 释放map
            m_map = 0;
        }
    }

protected:
    void m_initialize_map(size_t num_elements)
    {
        size_t num_nodes = num_elements / deque_buf_size(sizeof(Tp)) + 1;

        m_map_size = std::max((size_t)s_initial_map_size, num_nodes + 2); // +2是map前后都会预留空间
        m_map = (Tp**)malloc(m_map_size * sizeof(Tp*));

        Tp** nstart = m_map + (m_map_size - num_nodes) / 2;
        Tp** nfinish = nstart + num_nodes;

        for (Tp** cur = nstart; cur < nfinish; ++cur)
        {   // map的每一个node指向一个buf缓存
            *cur = (Tp*)malloc(deque_buf_size(sizeof(Tp)) * sizeof(Tp));
            printf("%p\n", *cur);
        }
        printf("\n");
        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));
    }
    enum { s_initial_map_size = 8 };

    Tp**        m_map;        //中控器,存放每个buf的首地址,用于管理buf
    size_t        m_map_size; //指针数组的长度
    iterator    m_start;    //指向第一个迭代器
    iterator    m_finish;    //指向最后一个迭代器
};

template <class Tp>
class Mydeque : public Deque_base<Tp>
{
    typedef Deque_base<Tp> Base;
public:                        
    typedef Tp value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
    typedef size_t size_type;
    typedef typename Base::iterator    iterator;

protected:                      
    typedef pointer* Map_pointer;
    static size_t s_buffer_size() { return deque_buf_size(sizeof(Tp)); }
    using Base::m_map;
    using Base::m_map_size;
    using Base::m_start;
    using Base::m_finish;
public:                         
    iterator begin() { return Base::m_start; }
    iterator end() { return m_finish; }
    reference operator[](size_type n)
    {
        return m_start[n];
    }

    reference front() { return *m_start; }
    reference back() 
    {
        iterator tmp = m_finish;
        --tmp;
        return *tmp;
    }
    size_type size() const { return m_finish - m_start; }
    bool empty() const { return m_finish == m_start; }

public:                       
    Mydeque() : Base(0) {}
    Mydeque(size_type n) : Base(n)
    {
        for (iterator it = m_start; it != m_finish; ++it)
        {
            new (it.m_cur) Tp();
        }
    }
    Mydeque(const Mydeque& x) : Base(x.size())
    {
        iterator tmp = m_start;
        for (iterator it = x.begin; it != x.end(); ++it, ++tmp)
        {
            new (tmp.m_cur) Tp(*it);
        }
    }

    ~Mydeque() 
    { 
        for (iterator it = m_start; it != m_finish; ++it)
        {
            (it.m_cur)->~Tp();
        }
    }

    void swap(Mydeque& 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 push_back(const value_type& t) 
    {
        if (m_finish.m_cur != m_finish.m_last - 1) 
        { // 如果buf还有空间
            new (m_finish.m_cur) Tp(t);
            ++m_finish.m_cur; // 只需要改下m_cur
        }
        else
        {
            m_push_back_aux(t);
        }
    }

    void push_front(const value_type& t) 
    {
        if (m_start.m_cur != m_start.m_first) 
        {
            new (m_start.m_cur - 1) Tp(t);
            --m_start.m_cur;
        }
        else
        {
            m_push_front_aux(t);
        }
    }

    void pop_back() 
    {
        if (m_finish.m_cur != m_finish.m_first) 
        {
            --m_finish.m_cur;
            ((value_type*)m_finish.m_cur)->~value_type();
        }
        else
        {
            m_pop_back_aux();
        }
    }

    void pop_front() 
    {
        if (m_start.m_cur != m_start.m_last - 1) 
        {
            ((value_type*)m_start.m_cur)->~value_type();
            ++m_start.m_cur;
        }
        else
        {
            m_pop_front_aux();
        }
    }
protected:
    // 只有在需要向后新增node时调用
    void m_push_back_aux(const value_type& t)
    {
        m_reserve_map_at_back();
        *(m_finish.m_node + 1) = (Tp*)malloc(deque_buf_size(sizeof(Tp)) * sizeof(Tp));
        printf("m_push_back_aux, %p\n", *(m_finish.m_node + 1));
        new (m_finish.m_cur)  Tp(t);
        m_finish.m_set_node(m_finish.m_node + 1);// m_finish指向下一个地址的首地址
        m_finish.m_cur = m_finish.m_first;
    }
    // 只有在需要向前新增node时调用
    void m_push_front_aux(const value_type& t)
    {
        m_reserve_map_at_front();
        *(m_start.m_node - 1) = (Tp*)malloc(deque_buf_size(sizeof(Tp)) * sizeof(Tp));
        printf("m_push_front_aux, %p\n", *(m_start.m_node - 1));
        m_start.m_set_node(m_start.m_node - 1);
        m_start.m_cur = m_start.m_last - 1;
        new (m_start.m_cur)  Tp(t);
    }
    // m_finish要跳到上一个node的时候才使用
    void m_pop_back_aux()
    {
        free(m_finish.m_first);
        m_finish.m_set_node(m_finish.m_node - 1);
        m_finish.m_cur = m_finish.m_last - 1;
        ((value_type*)m_finish.m_cur)->~value_type();
    }
    // m_start要跳到下一个node的时候才使用
    void m_pop_front_aux()
    {
        ((value_type*)m_start.m_cur)->~value_type();
        free(m_start.m_first);
        m_start.m_set_node(m_start.m_node + 1);
        m_start.m_cur = m_start.m_first;
    }
            
    // 向后添加map空间
    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);
        }
    }

    // 向前添加map空间
    void m_reserve_map_at_front(size_type nodes_to_add = 1) 
    {
        if (nodes_to_add > size_type(m_start.m_node - m_map))
        {
            m_reallocate_map(nodes_to_add, true);
        }
    }
    // 调整map空间大小
    // nodes_to_add-- 新添加的节点数 
    // add_at_front true-向前添加 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;

            Tp** 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)
                {
                    // 从m_start.m_node拷贝到new_nstart开始递增拷贝
                    std::copy(m_start.m_node, m_finish.m_node + 1, new_nstart);
                }
                else
                {   
                    // 从m_finish.m_node + 1拷贝到new_nstart + old_num_nodes开始递减拷贝
                    std::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 + std::max(m_map_size, nodes_to_add) + 2;

                Tp** new_map = (Tp**)malloc(new_map_size * sizeof(Tp*)); 
                new_nstart = new_map + (new_map_size - new_num_nodes) / 2
                    + (add_at_front ? nodes_to_add : 0);
                std::copy(m_start.m_node, m_finish.m_node + 1, new_nstart);
                free(m_map);
                m_map = new_map;
                m_map_size = new_map_size;
            }
            // 从新设置迭代器所在node
            m_start.m_set_node(new_nstart);
            m_finish.m_set_node(new_nstart + old_num_nodes - 1);
        }
    }
};

 

posted @ 2021-03-02 11:14  ho966  阅读(231)  评论(0编辑  收藏  举报