zoukankan      html  css  js  c++  java
  • STL之deque容器

    摘要:本文主要介绍了deque容器以及一些API的使用。

    1、基本概念

    1.1 deque容器介绍

    该容器和vector容器很相似,不同之处在于两点:第一是它可以实现头部的插入和删除;第二在于deque没有容量的概念,因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

    1.2 实现原理

    Deque容器是连续的空间,至少逻辑上看来如此,连续现行空间总是令我们联想到array和vector,array无法成长,vector虽可成长,却只能向尾端成长,而且其成长其实是一个假象,事实上(1) 申请更大空间 (2)原数据复制新空间 (3)释放原空间 三步骤,如果不是vector每次配置新的空间时都留有余裕,其成长假象所带来的代价是非常昂贵的。

    Deque是由一段一段的定量的连续空间构成。一旦有必要在deque前端或者尾端增加新的空间,便配置一段连续定量的空间,串接在deque的头端或者尾端。Deque最大的工作就是维护这些分段连续的内存空间的整体性的假象,并提供随机存取的接口,避开了重新配置空间,复制,释放的轮回,代价就是复杂的迭代器架构。

    既然deque是分段连续内存空间,那么就必须有中央控制,维持整体连续的假象,数据结构的设计及迭代器的前进后退操作颇为繁琐。Deque代码的实现远比vector或list都多得多。

    Deque采取一块所谓的map(注意,不是STL的map容器)作为主控,这里所谓的map是一小块连续的内存空间,其中每一个元素(此处成为一个结点)都是一个指针,指向另一段连续性内存空间,称作缓冲区。缓冲区才是deque的存储空间的主体。

    2、常用API

    2.1 deque构造函数

    deque<T> deqT 默认构造形式
    deque(beg, end) 构造函数将[beg, end)区间中的元素拷贝给本身
    deque(n, elem) 构造函数将n个elem拷贝给本身
    deque(const deque &deq) 拷贝构造函数

    2.2 deque赋值操作

    assign(beg, end) 将[beg, end)区间中的数据拷贝赋值给本身
    assign(n, elem) 将n个elem拷贝赋值给本身
    deque& operator=(const deque &deq) 重载等号操作符
    swap(deq) 将deq与本身的元素互换

    2.3 deque大小操作

    deque.size() 返回容器中元素的个数
    deque.empty() 判断容器是否为空
    deque.resize(num)

    重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    如果容器变短,则末尾超出容器长度的元素被删除

    deque.resize(num, elem)

    重新指定容器的长度为num,若容器变长,则以elem值填充新位置,

    如果容器变短,则末尾超出容器长度的元素被删除

    2.4 deque双端插入和删除操作

    push_back(elem) 在容器尾部添加一个数据
    push_front(elem) 在容器头部插入一个数据
    pop_back() 删除容器最后一个数据
    pop_front() 删除容器第一个数据

    2.5 deque数据存取

    at(idx) 返回索引idx所指的数据,如果idx越界,抛出out_of_range
    operator[] 返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错
    front() 返回第一个数据
    back() 返回最后一个数据

    2.6 deque插入操作

    insert(pos,elem) 在pos位置插入一个elem元素的拷贝,返回新数据的位置
    insert(pos,n,elem) 在pos位置插入n个elem数据,无返回值
    insert(pos,beg,end) 在pos位置插入[beg,end)区间的数据,无返回值

    2.7 deque删除操作

    clear() 移除容器的所有数据
    erase(beg,end) 删除[beg,end)区间的数据,返回下一个数据的位置
    erase(pos) 删除pos位置的数据,返回下一个数据的位置

    3、代码示例

     1 #include <iostream>
     2 #include<deque>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 void printDeque(const deque<int>&d) {
     8     for (deque<int>::const_iterator it=d.begin();it!=d.end();it++)
     9     {
    10         cout << *it <<"  ";
    11     }
    12     cout << endl;
    13 }
    14 
    15 void test01() {
    16     deque<int>d1;
    17     d1.push_back(10);
    18     d1.push_back(20);
    19     d1.push_front(5);  //注意可以前面插入
    20     d1.push_back(30);
    21     printDeque(d1);
    22 
    23     deque<int>d2(d1.begin(),d1.end()); //将d1首尾区间的内容复制到d2
    24     printDeque(d2);
    25     d2.push_back(40);
    26     printDeque(d2);
    27 
    28     d1.swap(d2);  //交换
    29     printDeque(d2);
    30 }
    31 
    32 void test02()
    33 {
    34     deque<int>d;
    35     d.push_back(10);
    36     d.push_back(30);
    37     d.push_back(20);
    38     d.push_front(100);
    39     d.push_front(200);
    40 
    41     printDeque(d); // 200 100 10 30 20
    42 
    43     //删除 头删 尾删
    44     d.pop_back();
    45     d.pop_front();
    46     printDeque(d); // 100 10 30
    47 
    48     cout << "front: " << d.front() << endl;
    49     cout << "back: " << d.back() << endl;
    50 
    51     //插入
    52     deque<int>d2;
    53     d2.push_back(50);
    54     d2.push_back(60);
    55     d2.insert(d2.begin(), d.begin(), d.end());
    56     printDeque(d2);  //  100 10 30 50 60
    57 }
    58 
    59 bool myCompare(int v1, int v2)
    60 {
    61     return v1 > v2; // 100 10
    62 }
    63 
    64 //排序 sort
    65 void test03()
    66 {
    67     deque<int>d;
    68     d.push_back(5);
    69     d.push_back(15);
    70     d.push_back(3);
    71     d.push_back(40);
    72     d.push_back(7);
    73 
    74     printDeque(d);
    75     //排序
    76     sort(d.begin(), d.end());
    77 
    78     printDeque(d);
    79 
    80     //从大到小
    81     sort(d.begin(), d.end(), myCompare);
    82     //从小到大
    83     //sort(d.begin(), d.end());
    84     printDeque(d);
    85 
    86 }
    87 
    88 int main() {
    89     //test01();
    90     //test02();
    91     test03();
    92     system("pause");
    93     return 0;
    94 }
  • 相关阅读:
    PartialView
    常用取默认值
    迁移环境或升级正常功能出bug常见原因
    模拟登陆语法
    fsg报表相关
    常用数组定义方式
    to_char函数 官方文档详解(数字格式转换和日期转换)
    个人工作window10常用快捷键
    ebs常见概念解释
    常用ASCII码和字符的转换
  • 原文地址:https://www.cnblogs.com/lzy820260594/p/11378398.html
Copyright © 2011-2022 走看看