0
点赞
收藏
分享

微信扫一扫

C/C++编程:STL deque

幸甚至哉歌以咏志 2022-04-01 阅读 102
leetcodeC++

vector VS deque

  • vector是单向开口的连续线性空间,deque则是一种双向开口的连续线性空间。
    • 所谓双向开口,指的是可以在头尾两端做元素的插入和删除操作
    • vector虽然技术上可以做到双向开口,但是在头部操作的效率非常差,无法被接受

在这里插入图片描述

  • deque和vector的最大差异:

    • 一是:在于deque允许常数级别对头部插入或者删除
    • 二是:deque没有所谓容量(capacity)观念
      • 因为deque是动态的以分段连续空间组合而成,随时可以增加一段新的空间并连接起来。而vector是”旧空间不足就申请一个更大的空间,然后复制元素,再释放旧空间“。
      • 也因此,deque没有必要提供所谓的空间保留(reserve)功能
  • 虽然deque也提供随机存取迭代器,但是它的迭代器并不是普通指针,其复杂度比vector高太多了,这也影响了各个运算层面。所以,除非必要,我们应该尽可能的选择vector而不是deque

#include <iostream>
#include <list>
#include <vector>
#include <queue>

std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
    for (auto &i : list) {
        ostr << " " << i;
    }
    return ostr;
}

int main()
{


    std::queue<int> myqueue;

    myqueue.push(12);
    myqueue.push(20);
    myqueue.push(75);

    printf("myqueue.back: %d, myqueue.front: %d\n", myqueue.back(), myqueue.front());


    std::vector<int> myvector;
    myvector.push_back(12);
    myvector.push_back(20);
    myvector.push_back(75);


    printf("myvector.back: %d, myvector.front: %d\n",  *(--myvector.end()), *myvector.begin());
}

在这里插入图片描述

deque的中控器

deque是连续空间(逻辑上),C++中连续线性空间有array和vector。

  • array无法成长
  • vector虽然可以成长,但是只能向尾端成长,而且其所谓成长其实是个假象。
    • 事实上是(1)另找一个更大空间(2)将原数据复制过去(3)释放原空间三部曲。
    • 如果不是vector每次配置新空间都会留下一些余地,那么代价会非常高
  • deque是有一段一段的定量连续空间构成
    • 一旦有必要再deque的前端或尾端增加空间,就配置一段定量连续空间,串接再整个deque的头部或者尾部
    • deque的最大任务,就是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随机存取的接口,避开”重新申请、复制、释放“的三部曲,代价是复杂的迭代器架构。

deque为了维持这个整体连续的假象,设置了一个中控器作为主控。

  • 这个所谓的主控可以看成是一个map(注意不是STL中的map)
  • 这个map是一小块连续空间,其中每个元素节点(node)都是指针,指向另一端较大的连续线性空间,称为缓冲区。
  • 缓冲区才是deque的存储空间主体。
  • STL允许我们指定缓冲区大小,默认值0表示将使用512bytes缓冲区

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

  • 把各种令人头皮发麻的型别定义(为了型别安全,这是必要的)整理一下,我们可以发现,map其实是一个T**。也就是说它是一个指针,所指之物又是一个指针,指向类型为T的一块空间

在这里插入图片描述

deque的迭代器

deque是分段连续空间,维持其”整体连续“假象的任务,落在了迭代器的operator++operator--两个运算子身上。

一个deque迭代器应该满足如下条件:

  • 首先,它必须能够指出分段连续空间(也就是缓冲区)在哪里
  • 其次,它必须能够判断自己是否已经处于其所在缓冲区的边缘
    • 如果是,一旦前进或者后退就必须跳到下一个或者上一个缓冲区。
    • 为了正确跳跃,deque必须随时掌握掌控中心map

在这里插入图片描述

举报

相关推荐

0 条评论