STL中有关deque、stack、queue、priority_queue

deque

deque中的修改类接口
由于deque是双端队列,所以有头插头删和尾插尾删操作。
下面的栈和队列的底层都是通过的deque实现的。
为什么要用deque作为其底层数据结构呢?
主要是因为:栈和队列都只需在一头进行操作,故不需要迭代器,只要具有pushback和popback的功能即可,在元素增长时deque比vector效率更高、内存使用率高,所以用deque作为底层数据结构更合适。

stack


根据文档里的内容我们可以看到stack中有这些接口。
在使用时要包含stack头文件
因为其底层是用deque实现的:所以有关它的模拟实现也就是对deque的一个封装。
例如:

template<class T,class Container=deque<T>>
    class stack//栈
    {
    public:
        stack()
        {

        }

        void push(const T&data)
        {
            _con.push_back(data);
        }
        private:
        Container _con;
    }


queue


注意队列不同的是由front和back操作,分别是队首和队尾元素。



priority_queue优先队列

底层使用堆实现的!
创建优先队列的默认是按照大堆(比较参数是less)方式!也就是说每个根节点都大于它的孩子节点。

构造函数:std::priority_queue<int, std::vector<int>, std::greater<int> >
third (myints,myints+4);
上例是构造了一个小堆类型的优先级队列
它的模板参数列表:template&lt;class T, class Container=vector&lt;T&gt;, class Compare=less&lt;T&gt;&gt;
所以如果想要用小堆创建对象时要把第三个参数改为great。

这里我们把库函数中的less这个函数拿来看一下:

template<class _Ty = void>
    struct less
        : public binary_function<_Ty, _Ty, bool>
    {   // functor for operator<
    bool operator()(const _Ty& _Left, const _Ty& _Right) const
        {   // apply operator< to operands
        return (_Left < _Right);
        }
    };

如果在优先级队列内存放自定义类型数据,需要需要用户提供<、>的重载,有时也要对提供比较器规则,参考less和greater在库函数中的实现,即对()进行重载。



模拟实现优先级队列:

namespace mine
    {
        template <class T, class Container = vector<T>, class Compare = less<T>>//默认(less)创建的是大堆
        class priority_queue
        {
        public:
            priority_queue()
                :c()
            {}

            template<class Iterator>
            priority_queue(Iterator first, Iterator last)//区间构造,将root进行向下调整
                : c(first, last)
            {
                // 将c中的元素调整成堆的结构
                int count = c.size();
                int root = ((count - 2) >> 1);
                for (; root >= 0; root--)
                    AdjustDown(root);
            }

            void push(const T & data)
            {
                c.push_back(data);
                AdjustUP(c.size()-1);//传入下标
            }

            void pop()//头删的话先将头元素与最后一个元素交换,把最后一个元素删掉后再执行向下排序
            {
                if (empty())
                    return;
                else
                {
                    swap(c.front(), c.back());
                    c.pop_back();
                    AdjustDown(0);
                }
            }
            int size()const
            {
                return c.size();
            }
            bool empty()const
            {
                return c.empty();
            }
            const T & top()const
            {
                return c.front();
            }

        private:

            //这里的向上调整和向下调整都是大堆模式
            void AdjustDown(int parent)//向下调整算法,把较小元素调整下去
            {
                int child = parent * 2 + 1;//child代表下标
                while (child < c.size())
                {
                    //找到以parent为根的较大的孩子
                    //如果根有右孩子并且左孩子比右孩子小,让child等于右孩子
                    //即child此时为较大的孩子
                    if (child + 1 < c.size() && com(c[child], c[child + 1]))
                    {
                        child = child + 1;
                    }
                    //如果孩子节点比父亲节点大则交换
                    if (com(c[parent], c[child]))
                    {
                        swap(c[child], c[parent]);
                        parent = child;
                        child = parent * 2 + 1;
                    }
                    else
                        return;
                }
            }

            void AdjustUP(int child)//向上调整算法,将较大元素调整上去
            {
                int parent = (child - 1) >> 1;
                while (child)//没有到根的话继续循环
                {
                    //如果父亲节点比孩子节点小,交换
                    //将较大节点调整到根位置
                    if (com(c[parent], c[child]))
                    {
                        swap(com(c[parent], c[child]));
                        child = parent;
                        parent = (child - 1) >> 1;
                    }
                    else
                    {
                        return;
                    }
                }
            }
        private:
            Container c;
            Compare com;
        };
    }

这里最重要的就是向上调整和向下调整算法,同时也要注意比较规则在其中的用法。详细过程见代码注释。

原文地址:https://blog.51cto.com/14239789/2444759

时间: 2024-11-15 00:57:00

STL中有关deque、stack、queue、priority_queue的相关文章

UVA11995I Can Guess the Data Structure!(stack + queue + priority_queue)

题目:UVA11995I Can Guess the Data Structure!(stack + queue + priority_queue) 题目大意:给你两种指令,1代表让1后面的数字进入这个数据结构,2代表无差错的从数据结构中取出这个数字,问这个数据结构是stack还是queue还是priority_queue,还是不确定,还是以上均不可能. 解题思路:用STL中的这些数据结构来模拟一下,模拟成功就是这种数据结构,注意pop的时候要判断是否empty. 代码: #include <c

stack queue priority_queue

可以直接使用的数据结构 stack queue priority_queue 头文件 <stack> <queue> <queue> 声明 stack<int>s1 queue<int>q; #include<functional> #include<vector> priority_queue<int,vector<Int>,less<Int>> pq; 从小到大 容量 s1.size

STL stack queue priority_queue

栈: empty() pop() push() size() top() 队列: back() empty() front() pop() push() size() 优先队列: empty() pop() push() size() top() priority_queue<int>  pq;   默认升序 priority_queue<int, vector<int>, greater<int> >  pq; 降序 priority_queue<i

C++ 顺序容器(vector,list、deque,stack,queue)

顺序容器的种类有:vector,list.deque 顺序容器适配器: stack     //先进后出   栈 queue   //先进先出   队列 priority_queue   //也优先管理级的优先队列 1.头文件 #include <vector> #include <list> #include <deque> //每一种头文件对应一种顺序容器 #include <queue> //队列 优先队列的头文件 #include <stack

uva 11995 I Can Guess the Data Structure stack,queue,priority_queue

题意:给你n个操做,判断是那种数据结构. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<stack> 5 #include<queue> 6 using namespace std; 7 int n; 8 int v[1010],u[1010]; 9 10 int ck_q() 11 { 12 //cout<<"!!"&

STL容器用法速查表:list,vector,stack,queue,deque,priority_queue,set,map

STL容器用法速查表:list,vector,stack,queue,deque,priority_queue,set,map   list vector deque stack queue priority_queue set [unordered_set] map [unordered_map] multimap [unordered_multimap]     contiguous storage double-ended queue LIFO FIFO 1st is greatest  

STL中队列(queue)的使用方法

STL 中队列的使用(queue) 基本操作: push(x) 将x压入队列的末端 pop() 弹出队列的第一个元素(队顶元素),注意此函数并不返回任何值 front() 返回第一个元素(队顶元素) back() 返回最后被压入的元素(队尾元素) empty() 当队列为空时,返回true size() 返回队列的长度 使用方法: 头文件: #include <queue> 声明方法: 1.普通声明 queue<int>q; 2.结构体 struct node { int x, y

STL中栈和队列的使用方法

 STL 中优先队列的使用方法(priority_queu) 基本操作: empty() 如果队列为空返回真 pop() 删除对顶元素 push() 加入一个元素 size() 返回优先队列中拥有的元素个数 top() 返回优先队列对顶元素 在默认的优先队列中,优先级高的先出队.在默认的int型中先出队的为较大的数. 使用方法: 头文件: #include <queue> 声明方式: 1.普通方法: priority_queue<int>q; //通过操作,按照元素从大到小的顺

stack, deque 和 queue的对比

stack, deque 和 queue这三个c++的STL的数据结构很类似但又各有不同. stack是堆栈,没有迭代器,特点是后进先出.用push()将元素压入栈中,top()返回栈顶元素,pop()移除栈顶元素. deque是双端队列,支持迭代器,使用push_back()在队尾添加元素,pop_back()移除队尾元素,这些跟vector差不多.不同的地方在于deque还可在队首添加和移除元素,使用pop_front()和push_front(). queue是队列,特点是先进先出,不支持