码迷,mamicode.com
首页 > 其他好文 > 详细

STL之序列化容器

时间:2021-04-08 13:03:24      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:全局   排序   内存   标准   完成   源码剖析   c++   指定   效率   

序列化容器

以线性排列(类似普通数组的存储方式)来存储某一指定类型(例如 int、double 等)的数据。需要特殊说明的是,该类容器并不会自动对存储的元素按照值的大小进行排序。
STL提供了vector,list,deque,stack,queue,priority-queue。其中stack,queue(它们都是在 deque 容器的基础上改头换面而成)
在技术上被归为配接器(adapter),但《STL源码剖析》还是在序列化容器这节讲了。另外,C++11引入了array序列式容器。

  • array<T,N>(数组容器):表示可以存储 N 个 T 类型的元素,是 C++ 本身提供的一种容器。此类容器一旦建立,
    其长度就是固定不变的,这意味着不能增加或删除元素,只能改变某个元素的值;
  • vector(向量容器):用来存放 T 类型的元素,是一个长度可变的序列容器,即在存储空间不足时,会自动申请更多的内存。使用此容器,在尾部增加或删除元素的效率最高(时间复杂度为 O(1) 常数阶),在其它位置插入或删除元素效率较差(时间复杂度为 O(n) 线性阶,其中 n 为容器中元素的个数);
  • deque(双端队列容器):和 vector 非常相似,区别在于使用该容器不仅尾部插入和删除元素高效,在头部插入或删除元素也同样高效,时间复杂度都是 O(1) 常数阶,但是在容器中某一位置处插入或删除元素,时间复杂度为 O(n) 线性阶;
  • list(链表容器):是一个长度可变的、由 T 类型元素组成的序列,它以双向链表的形式组织元素,在这个序列的任何地方都可以高效地增加或删除元素(时间复杂度都为常数阶 O(1)),但访问容器中任意元素的速度要比前三种容器慢,这是因为 list 必须从第一个元素或最后一个元素开始访问,需要沿着链表移动,直到到达想要的元素。
  • forward_list(正向链表容器):和 list 容器非常类似,只不过它以单链表的形式组织元素,它内部的元素只能从第一个元素开始访问,是一类比链表容器快、更节省内存的容器。

array

  • array 容器是 C++ 11 标准中新增的序列容器,简单地理解,它就是在 C++ 普通数组的基础上,添加了一些成员函数和全局函数。
  • 在使用上,它比普通数组更安全(有更多的检测函数,比如at(n),检测第n位元素的引用是否在合法范围),且效率并没有因此变差。
  • 需要引入头文件array
    几种常见初始化方式:
  1. std::array<double, 10> values;//随机值
  2. std::array<double, 10> values {};//默认0.0
  3. std::array<double, 10> values {0.5,1.0,1.5,,2.0};//其余初始化为0.0

vector

  • 动态数组,擅长在尾部插入或者删除元素(时间复杂度O(1)),其他位置则是O(n)
  • 需要引入 vector 头文件
  • 当发生大小变化引发内存变化时(一般指扩容),需要注意已获取的迭代器会失效
  • vector 容器的容量(用 capacity 表示),指的是在不分配更多内存的情况下,容器可以保存的最多元素个数;
    而 vector 容器的大小(用 size 表示),指的是它实际所包含的元素个数。
  • vector的迭代器就是普通指针,另外底层是三个指针在作用,start,finish,end_of_storage
    几种常见初始化方式:
  1. std::vector values; //注意,这是个空容器,用push_back或者reserve函数初始化容量
  2. std::vector primes {2, 3, 5, 7, 11, 13, 17, 19};
  3. std::vector values(20);//默认值0.0
  4. std::vector values(20,1.0);//默认值1.0
  5. std::vector values(其他vector容器);

deque

  • deque则是一种双向开口连续线性空间,此处的连续指的是一段空间的连续(称为缓冲区),deque拥有多个这样的缓冲区。但操作起来无感
    技术图片

  • 迭代器示例图,指向开始和结束的缓冲区
    技术图片

  • 上图是deque底层结构的大体构成
    技术图片

  1. curr指向当前缓冲区现行元素
  2. first指向当前缓冲区的头
  3. last指向当前缓冲区的尾(包含备用空间,一般预留一个,到这就会新开辟缓冲区)
  4. node指向管控中心map(指向指针(map自己的)的指针(缓冲区的))
  5. 注意push_front(判定条件start.curr != start.first)在内部实现上指针的走向是和push_back(判定条件finish.curr!= finish.last - 1(预留一个空间))反着的
    我认为正向不需要预留是因为从头开始一般是满的,符合逻辑

几种常见初始化方式:

  1. std::deque d;//空的,可以通过 push_back()、push_front() 或者 resize() 成员函数实现向(空)deque 容器中添加元素。
  2. std::deque d(10);//有默认值0
  3. std::deque d(10, 5)//有默认值5
  4. std::deque d1(5);
    std::deque d2(d1);//拷贝其他容器
  5. //拷贝普通数组,创建deque容器
    int a[] = { 1,2,3,4,5 };
    std::dequed(a, a + 5);
    //适用于所有类型的容器
    std::array<int, 5>arr{ 11,12,13,14,15 };
    std::dequed(arr.begin()+2, arr.end());//拷贝arr容器中的{13,14,15}

list

  • list本身和list节点是不同的设计。节点是具有prev、next双向指针的结构。而list本身只需要一个指针即可完成遍历整个列表
  • list不仅是个双向链表,而且还是一个环状双向链表
    技术图片

几种常见初始化方式:参照deque

forward_list

  • 单向链表,更省内存,只能 从头开始找只有push_front操作
  • C+11引入,未纳入标准前在STL也叫slist

STL之序列化容器

标签:全局   排序   内存   标准   完成   源码剖析   c++   指定   效率   

原文地址:https://www.cnblogs.com/ming-fei/p/14619678.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!