• 双端队列-deque【集vector与list于一身的牺牲内存换功能完善】


     看到双端队列(deque)了,书上是这样说的:除了栈和队列外还有一种限定性数据结构是双端队列;双端队列是限定插入和删除操作在表的两端进行的线性表;尽管双端队列看起来似乎比栈和队列更灵活,但实际上在应用程序中远不及栈和队列有用,故在此不作详细讨论。于是乎就跳了过去讲链队列和循环队列去了,我想反正是复习嘛,没有考试的压力,不要放过就是了,再说就算双端队列远不及栈和队列有用,也要知道怎么个没用法。所以就查了下:

                                                    Deque成员函数

    函数
    描述
    c.assign(beg,end)
    c.assign(n,elem)
    将[beg; end)区间中的数据赋值给c。
    将n个elem的拷贝赋值给c。
    c.at(idx)
    传回索引idx所指的数据,如果idx越界,抛出out_of_range。
    c.back()
    传回最后一个数据,不检查这个数据是否存在。
    c.begin()
    传回迭代器重的可一个数据。
    c.clear()
    移除容器中所有数据。
    deque<Elem> c
    deque<Elem> c1(c2)
    Deque<Elem> c(n)
    Deque<Elem> c(n, elem)
    Deque<Elem> c(beg,end)
    c.~deque<Elem>()
    创建一个空的deque。
    复制一个deque。
    创建一个deque,含有n个数据,数据均已缺省构造产生。
    创建一个含有n个elem拷贝的deque。
    创建一个以[beg;end)区间的deque。
    销毁所有数据,释放内存。
    c.empty()
    判断容器是否为空。
    c.end()
    指向迭代器中的最后一个数据地址。
    c.erase(pos)
    c.erase(beg,end)
    删除pos位置的数据,传回下一个数据的位置。
    删除[beg,end)区间的数据,传回下一个数据的位置。
    c.front()
    传回地一个数据。
    get_allocator
    使用构造函数返回一个拷贝。
    c.insert(pos,elem)
    c.insert(pos,n,elem)
    c.insert(pos,beg,end)
    在pos位置插入一个elem拷贝,传回新数据位置。
    在pos位置插入>n个elem数据。无返回值。
    在pos位置插入在[beg,end)区间的数据。无返回值。
    c.max_size()
    返回容器中最大数据的数量。
    c.pop_back()
    删除最后一个数据。
    c.pop_front()
    删除头部数据。
    c.push_back(elem)
    在尾部加入一个数据。
    c.push_front(elem)
    在头部插入一个数据。
    c.rbegin()
    传回一个逆向队列的第一个数据。
    c.rend()
    传回一个逆向队列的最后一个数据的下一个位置。
    c.resize(num)
    重新指定队列的长度。
    c.size()
    返回容器中实际数据的个数。
    C1.swap(c2)
    Swap(c1,c2)
    将c1和c2元素互换。
    同上操作。
    operator[] 返回容器中指定位置的一个引用。

    又搜到了一个使用C++ STL容器基本操作的博客 http://hi.baidu.com/xuehuo_0411/blog/item/c225942c0a02033a349bf7d1.html,后我照着一些简单的程序写了遍,

    代码如下:

    双端队列容器(deque)

      

    亲手写了后,觉得deque还是很好用的啊,就搜了下“C++ STL deque的缺点”,觉得这人讲的不错,还做了对比http://blog.csdn.net/ianleelj/article/details/3939354,内容不多就贴下吧,

     1 vector

        向量 相当于一个数组
        在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacituy()函数返回的大小,当超过此分配的空间时再整体重新放分配一块内存存储,这给人以vector可以不指定vector即一个连续内存的大小的感觉。通常此默认的内存分配能完成大部分情况下的存储。
       优点:(1) 不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组
                   进行动态操作。通常体现在push_back() pop_back()
                   (2) 随机访问方便,即支持[ ]操作符和vector.at()
                   (3) 节省空间。
       缺点:(1) 在内部进行插入删除操作效率低。
                   (2) 只能在vector的最后进行push和pop,不能在vector的头进行push和pop。
                   (3) 当动态添加的数据超过vector默认分配的大小时要进行整体的重新分配、拷贝与释
                         放 

    list
        双向链表
        每一个结点都包括一个信息快Info、一个前驱指针Pre、一个后驱指针Post。可以不分配必须的内存大小方便的进行添加和删除操作。使用的是非连续的内存空间进行存储。
       优点:(1) 不使用连续内存完成动态操作。
                   (2) 在内部方便的进行插入和删除操作
                   (3) 可在两端进行push、pop
       缺点:(1) 不能进行内部的随机访问,即不支持[ ]操作符和vector.at()
                   (2) 相对于verctor占用内存多

    deque
       双端队列 double-end queue
       deque是在功能上合并了vector和list。
       优点:(1) 随机访问方便,即支持[ ]操作符和vector.at()
                   (2) 在内部方便的进行插入和删除操作
                   (3) 可在两端进行push、pop
       缺点:(1) 占用内存多

    使用区别:

         1 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector 
         2 如果你需要大量的插入和删除,而不关心随即存取,则应使用list 
         3 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque

       

      看了后觉得deque还是很好用的嘛,虽然内存占用多些,但是也不至于像书上那样说的一无是处,deque像是集vector和list两者特性的一个容器,牺牲内存换的功能的完善也没什么不可以吧。

    (一)创建deque对象:
    (1)创建没有任何元素的deque对象:deque<int > d;   deque<float> dd;
    (2)创建具有n个元素的deque对象:deque<int> d(10);  //创建具有10个整形元素的deque对象d ;
    (3)创建具有n个元素的deque对象,并赋值:deque<int> d(10,8);  //创建具有10个整形元素的deque对象d,每个元素之为8。
    (二)插入元素:
    (1)使用push_back()方法从尾部插入元素,会不断扩张队列;
    (2)使用push_front()方法从头部插入元素,不会增加新元素,只将原有的元素覆盖;
    (3)使用insert()方法从中间插入元素,不会增加新元素,只将原有的元素覆盖。
    (三)遍历元素:
    (1)前向遍历:以数组方式遍历或以前向迭代器的方式遍历。
    (2)反向遍历:使用反向迭代器进行遍历。
    (四)删除元素:
    (1)pop_front()从首部删除元素;
    (2)pop_back()从尾部删除元素;
    (3)erase(迭代器)删除迭代器位置的元素;
    (4)clear()清空双端队列容器。
    

      

    /*1,2操作*/
    #include<iostream>    
    #include<deque>    
    #include<string>    
    using namespace std;    
        
    int main()    
    {    
        int i;  
        //初始化双端队列,  
        deque<int> d(4,1);  
        deque<int> ::iterator pos=d.begin();  
      
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
          
        //push_back尾部插入元素  
        d.push_back(2);  
              
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
      
        //push_front首部插入元素  
        d.push_front(0);  
          
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
      
        //insert从中间插入元素,不会增加新的元素,只将原来的覆盖  
        pos++;  
        d.insert(pos,9);  
      
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
      
        return 0;    
    }   
    输出结果如下,自行对照输出语句:  
    1 1 1 1  
    1 1 1 1 2  
    0 1 1 1 1 2  
    0 1 9 1 1 1 2  
    

      

    /*遍历元素*/
    #include<iostream>    
    #include<deque>    
    #include<string>    
    using namespace std;    
        
    int main()    
    {    
        int i;  
        //初始化双端队列,  
        deque<int> d;  
        deque<int> ::iterator pos;  
        deque<int> ::reverse_iterator pos1;  
        d.push_back(0);  
        d.push_back(1);  
        d.push_back(2);  
        d.push_back(3);  
        //数组方式顺序遍历  
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
        //迭代器方式遍历  
        for(pos=d.begin();pos!=d.end();pos++)  
            cout<<(*pos)<<" ";  
        cout<<endl;  
        //反向遍历  
        for(pos1=d.rbegin();pos1!=d.rend();pos1++)  
            cout<<(*pos1)<<" ";  
        cout<<endl;  
          
        return 0;    
    }   
    

      

    /*删除元素*/
    #include<iostream>    
    #include<deque>    
    #include<string>    
    using namespace std;    
        
    int main()    
    {    
        int i;  
        //初始化双端队列,  
        deque<int> d;  
        deque<int> ::iterator pos;  
        d.push_back(0);  
        d.push_back(1);  
        d.push_back(2);  
        d.push_back(3);  
        d.push_back(4);  
      
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
          
        //pop_front()从首部删除元素  
        d.pop_front();  
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
      
        //pop_back()从尾部删除元素;  
        d.pop_back();  
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
          
        //erase(迭代器)删除迭代器位置的元素  
        pos=d.begin();  
        d.erase(pos);  
        for(i=0;i<d.size();i++)  
            cout<<d[i]<<" ";  
        cout<<endl;  
          
        //清空双端队列  
        d.clear();  
        cout<<"size="<<d.size()<<endl;  
        return 0;    
    }   
    

      

  • 相关阅读:
    layui分页获取数据,回显checkbox
    批量选中 及下载
    Module Federation原理剖析
    EMP-面向未来微前端方案正式开源了!
    Vue3 也能用上 Vue2 组件 From EMP
    对比多种微前端方案
    EMP微前端之教你如何搭建共享站
    EMP微前端实战之cocos2d线上项目
    微前端是什么,可以带来什么收益
    Elasticsearch操作实践手册|建议收藏篇
  • 原文地址:https://www.cnblogs.com/Roni-i/p/8059221.html
Copyright © 2020-2023  润新知