zoukankan      html  css  js  c++  java
  • 【C++ STL】Deques

    1、结构

      容器deque和vector非常相似,也是采用动态数组来管理元素,提供随机存取,有着和vector几乎一样的接口,不同的是deque的动态数组头尾都开放,因此可以在头尾都可以进行快速的安插和删除。

      为了获取这种能力,deque通常实作为一组独立区块,第一区块朝某方向扩展,最后一区块朝另一方向扩展。

    2、deque能力

    2.1 与vector区别

      两端都能快速安插和删除元素。

      存取元素时,deque内部结构会多一个间接的过程,所以存取和迭代器的动作会稍微慢一些。

      迭代器需要在不同的内存区块跳转,所以必须是特殊的智能型指针,非一般指针。

      deque不支持对容量和内存重分配时机的控制,除了头尾两端,在任何地方删除或者增加元素都会使reference、pointers、iterators失效。deque的内存分配优于vector,由其内部可知,deque不必在内存重新分配时复制所有元素。

      deque的内存区块不再被使用时,会被释放。deque的内存大小是可缩减的。

    2.2 与vector的共同点

      在中段部分安插、移除元素的速度相对较慢,因为所有的元素都需要移动或者腾出填补空间。

      迭代器属于random access iterator(随机存取迭代器)。

    2.3 适用场景

      需要在两段安插或者删除元素

      无需引用容器内的元素

      要求释放不再使用的元素。

    3、操作函数

    3.1 构造函数和析构函数

    操作

    效果

    deque<Elem> c

    产生一个空的deque

    deque<Elem> c1(c2)

    针对某个同型deque产生一个副本(所有元素都被拷贝)

    deque<Elem> c(n)

    产生一个包含n个元素的deque,这些元素均以default构造函数产生。

    deque<Elem> c(n,elem)

    产生一个包含n个元素的deque,这些元素均是elem的副本

    deque<Elem> c(beg,end)

    产生一个deque,以区间[beg,end)内的元素作为初值

    c.~deque<Elem>()

    销毁所有元素,释放内存

    3.2 非变动操作

    操作

    效果

    c.size()

    返回当前的元素数量

    c.empty()

    判断大小是否为零,等同于0 == size(),效率更高

    c.max_size()

    返回能容纳的元素最大数量

    c1 == c2

    判断c1是否等于c2

    c1 != c2

    判断c1是否不等于c2(等同于!(c1==c2))

    c1 < c2

    判断c1是否小于c2

    c1 > c2

    判断c1是否大于c2

    c1 <= c2

    判断c1是否小于等于c2(等同于!(c2<c1))

    c1 >= c2

    判断c1是否大于等于c2 (等同于!(c1<c2))

    c.at(idx)

    返回索引idx所标示的元素,如果idx越界,抛出out_of_range

    c[idx]

    返回索引idx所标示的元素,不进行范围检查

    c.front()

    返回第一个元素,不检查第一个元素是否存在

    c.back()

    返回最后一个元素,不检查最后一个元素是否存在

    c.begin()

    返回一个随机存取迭代器,指向第一个元素

    c.end()

    返回一个随机存取迭代器,指向最后一个元素的下一个位置

    c.rbegin()

    返回一个逆向迭代器,指向逆向迭代的第一个元素

    c.rend()

    返回一个逆向迭代器,指向逆向迭代的最后一个元素的下一个位置

    3.3变动性操作

    操作

    效果

    c1 = c2

    将c2所有的元素赋值给c1

    c.assign(n,elem)

    将n个elem元素的副本赋值给c

    c.assign(beg,end)

    将区间[beg,end)所有的元素赋值给c

    c1.swap(c2)

    c1和c2的元素互换

    swap(c1,c2)

    c1和c2的元素互换,全局函数

    c.insert(pos,elem)

    在pos位置安插一个elem副本,返回新元素的位置

    c.insert(pos,n,elem)

    在pos位置安插n个elem副本,无返回值

    c.insert(pos,beg,end)

    在pos位置安插区间[beg,end)所有元素的副本,无返回值

    c.push_back(elem)

    在尾部添加一个elem副本

    c.pop_back()

    移除最后一个元素

    c.push_front(elem)

    在头部添加一个elem元素副本

    c.pop_front()

    移除头部元素

    c.erase(pos)

    移除pos位置上的元素,返回下一个元素的位置

    c.erase(beg,end)

    移除区间[beg,end)所有的元素,返回下一个元素的位置

    c. resize(num)

    将大小(元素个数)重置为num个,如果size()增大,新增元素都已default构造函数构造出来

    c.resize(num, elem)

    将大小(元素个数)重置为num个,如果size()增大,新增元素都是elem的副本

    c.clear()

    移除所有元素,容器清空

    3.4 注意

      deque不提供容量操作(capacity(),reserve())

      deque提供之间函数,完成头部的删除(pop_front())和插入(push_front ())操作。

       除了at(),没有任何成员函数会检查索引或者迭代器是否有效。

      元素的插入和删除可能导致内存的重新分配,所以任何插入和删除的动作都可能使所有指向deque元素的pointers、reference、iterators失效。唯一例外的是在头部或尾部插入元素,pointers和reference依然有效,但是iterators会失效。

    4、示例代码

    // cont/deque1. cpp
    
       #include <iostream>
       #include <deque>
       #include <string>
       #include <algorithm>
       using namespace std;
    
       int main()
       {
    
           //create empty deque of strings
           deque<string> coll;
    
           //insert several elements
           coll.assign (3, string("string"));
           coll.push_back ("last string");
           coll.push_front ("first string");
    
           //print elements separated by newlines
           copy (coll.begin(), coll.end(),
                 ostream_iterator<string>(cout,"
    "));
           cout << endl;
    
           //remove first and last element
           coll.pop_front();
           coll.pop_back();
    
           //insert ''another'' into every element but the first
           for (int i=1; i<coll.size(); ++i) {
               coll[i] = "another " + coll [i];
    
           }
    
           //change size to four elements
           coll.resize (4, "resized string");
    
           //print elements separated by newlines
           copy (coll.begin(), coll.end(),
                 ostream_iterator<string>(cout,"
    "));
    
       }

    输出:

       first string
       string
       string
       string
       last string
    
       string
       another string
       another string
       resized string
  • 相关阅读:
    【总结+计划】七八月份总结+九月份计划——未知的状态最可怕
    【总结+计划】六月份总结+七月份计划——实习 就业 自学
    【计划】六月自学计划
    【总结】五月份总结——到底前端还是后台好呢
    Android中如何让DialogFragment全屏
    有用的
    Android Studio多渠道打包的使用
    adb not responding的解决方案
    ButterKnife的使用
    程序中判断android系统版本
  • 原文地址:https://www.cnblogs.com/ChinaHook/p/6985324.html
Copyright © 2011-2022 走看看