C++:容器适配器的理解

什么是适配器

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该模式是将一个类的接口转换成客户希望的另外一个接口。
在这里插入图片描述

为什么将stack、queue和priority_queue称作为容器适配器

虽然stack、queue、priority_queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为每个容器在底层都有自己的实现方式,而stack、queue、priority_queue只是在底层将其他容器进行了封装,比如:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

模拟实现 stack、queue、priority_queue

代码示例:

namespace bit
{
#include<deque>
    template<class T, class Con = deque<T>>
    class stack
    {
    public:
        stack() 
        {}

        void push(const T& x) 
        { 
            _c.push_back(x); 
        }

        void pop() 
        { 
            _c.pop_back(); 
        }

        T& top() 
        { 
            return _c.back(); 
        }

        const T& top()const 
        { 
            return _c.back(); 
        }

        size_t size()const 
        { 
            return _c.size(); 
        }

        bool empty()const 
        { 
            return _c.empty(); 
        }
    private:
        Con _c;
    };
}

namespace bit {
#include<deque>
    template<class T, class Con = deque<T>>
    class queue
    {
    public:
        queue() 
        {}

        void push(const T& x) 
        { 
            _c.push_back(x); 
        }

        void pop() 
        { 
            _c.pop_front(); 
        }

        T& back() 
        { 
            return _c.back(); 
        }

        const T& back()const 
        { 
            return _c.back(); 
        }

        T& front() 
        { 
            return _c.front(); 
        }
        
        const T& front()const 
        { 
            return _c.front(); 
        }

        size_t size()const 
        { 
            return _c.size(); 
        }

        bool empty()const 
        { 
            return _c.empty(); 
        }
    private:
        Con _c;
    };
}

namespace bit
{
    template <class T, class Sequence = vector<T>, class Compare = less<T> >
    class priority_queue
    {
    public:
        priority_queue() : c()
        {}

        template <class InputIterator>
        priority_queue(InputIterator first, InputIterator last)
            : c(first, last)
        {
            make_heap(c.begin(), c.end(), comp);
        }

        bool empty() const 
        { 
            return c.empty(); 
        }

        size_t size() const 
        { 
            return c.size(); 
        }

        T& top() const 
        { 
            return c.front(); 
        }

        void push(const T & x)
        {
            c.push_back(x);
            push_heap(c.begin(), c.end(), comp);
        }

        void pop() {
            pop_heap(c.begin(), c.end(), comp);
            c.pop_back();
        }
    private:
        Sequence c;
        Compare comp;
    };
}

为什么选择deque作为stack和queue的底层默认容器

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有 push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stack和 queue默认选择deque作为其底层容器,主要是因为:

  1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. 在stack中元素增长时,deque比vector的效率高;queue中的元素增长时,deque不仅效率高,而且内存使用率高。

总结一句话 :deque在两端进行增长和删除的速度是最快的

要点总结:

stack queue
默认适配器 deque deque
可选适配器 vector、list list
需要操作 push => push_back、pop => pop_back、top => back push => push_back、pop => pop_front、back => back、front=> front

priority_queue:

#include (仿函数)
默认适配器:vector
默认比较方式:less

可选适配器:deque
可选比较方式:greater

#include (算法)

构造 => make_heap
push => push_back + push_heap
pop => pop_front + pop_heap
top => front

仿函数:可以当成函数使用的类,方法是重载函数调用运算符("()")


如有不同见解,欢迎留言讨论!

发布了152 篇原创文章 · 获赞 45 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/AngelDg/article/details/105334941