C++_STL——deque and vector
C++_STL——deque and vector
deque
template < class T, class Alloc = allocator<T> > class deque;
双端队列
vector和deque都提供了非常相似的API,可以用于类似的目的,但在内部都以完全不同的方式工作:虽然向量使用一个需要偶尔重新分配以增长的单个数组,但双端队列的元素可以分散在不同的存储块,容器在内部保存必要的信息,以在恒定时间内提供对其任何元素的直接访问,并具有统一的顺序接口(通过迭代器)。因此,双端队列在内部比向量要复杂一些,但是这允许它们在某些情况下更有效地增长,特别是对于非常长的序列,在这种情况下,重新分配变得更加昂贵。
因此,它们提供了类似于vector的功能,但在序列的开头,而不仅仅是在其末尾,还可以有效地插入和删除元素。但是,与vector不同,双端队列不能保证将其所有元素存储在连续的存储位置:通过将指针偏移到另一个元素来访问双端队列中的元素会导致未定义的行为。
特定的库可能以不同的方式实现双端队列,通常作为某种形式的动态数组。但无论如何,它们允许通过随机访问迭代器直接访问单个元素,并通过根据需要扩展和收缩容器来自动处理存储。
参数
T:元素类型
Alloc:用于定义存储分配模型的分配器对象的类型。 默认情况下使用分配器类模板,它定义了最简单的内存分配模型,并且与值无关。
容器特点
序列:序列容器中的元素以严格的线性顺序排列。 单个元素按其在此序列中的位置进行访问。
动态数组:通常作为动态数组实现,它允许直接访问序列中的任何元素,并在序列的开头或结尾提供相对快速的元素添加/删除。
动态分配: 容器使用分配器对象来动态处理其存储需求。
1、构造函数
构造函数 | |
---|---|
default (1) |
explicit deque (const allocator_type& alloc = allocator_type());
|
fill (2) |
explicit deque (size_type n); deque (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
|
range (3) |
template <class InputIterator> deque (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
|
copy (4) |
deque (const deque& x); deque (const deque& x, const allocator_type& alloc);
|
move (5) |
deque (deque&& x); deque (deque&& x, const allocator_type& alloc);
|
initializer list (6) |
deque (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());
|
(1) 空容器构造函数(默认构造函数)
构造一个没有元素的空容器。
(2) 填充构造函数
构造一个包含n个元素的容器。每个元素都是val的副本(如果提供)。
(3) 范围构造函数
构造一个包含与范围[第一,最后)相同数量的元素的容器,每个元素的安放位置都是从该范围内相应的元素以相同的顺序构造的。
(4) 复制构造函数(并使用分配器复制)
以相同的顺序构造一个包含x中每个元素的副本的容器。
(5) 移动构造函数(并使用分配器移动)
构造一个获取x元素的容器。
如果指定了alloc并且它与x的分配器不同,那么元素将被移动。否则,不会构造任何元素(它们的所有权直接转移)。
x处于未指定但有效的状态。
(6) 初始值设定项列表构造函数
以相同的顺序构造一个包含il中每个元素的副本的容器。
#include <iostream>
#include <deque>int main ()
{unsigned int i;// constructors used in the same order as described above:std::deque<int> first; // empty deque of intsstd::deque<int> second (4,100); // four ints with value 100std::deque<int> third (second.begin(),second.end()); // iterating through secondstd::deque<int> fourth (third); // a copy of third// the iterator constructor can be used to copy arrays:int myints[] = {16,2,77,29};std::deque<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );std::cout << "The contents of fifth are:";for (std::deque<int>::iterator it = fifth.begin(); it!=fifth.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
2、std::deque::at、back、begin、cbegin、end、cend、crbegin、crend、empty
请看这篇文章,含义一样C++_STL——array(C++11)
3、std::deque::assign
range (1) |
template <class InputIterator> void assign (InputIterator first, InputIterator last);
|
---|---|
fill (2) |
void assign (size_type n, const value_type& val);
|
initializer list (3) |
void assign (initializer_list<value_type> il);
|
3.1range (1)——参数输入迭代器[first,last),也可以传指针
输入迭代器,把一个deque(双向队列)的输入迭代器作为参数传入,新内容是从第一个和最后一个范围内的每个元素以相同的顺序构建的元素。
下面程序的指针传递:
third.assign (myints,myints+3); // assigning from array.
third.assign (&myints[0],&myints[0]+3); // assigning from array.
3.2fill (2)——参数n个val
新内容为 n 元素,每个元素初始化为 Val 副本。
3.3initializer list (3) ——参数列表类型,如{1,2,3}
新内容是作为初始化列表传递的值的副本,顺序相同。
3.4返回值无
// deque::assign
#include <iostream>
#include <deque>int main ()
{std::deque<int> first;std::deque<int> second;std::deque<int> third;first.assign (7,100); // 7 ints with a value of 100std::deque<int>::iterator it;it=first.begin()+1;second.assign (it,first.end()-1); // the 5 central values of firstint myints[] = {1776,7,4};third.assign (myints,myints+3); // assigning from array.std::cout << "Size of first: " << int (first.size()) << '\n';std::cout << "Size of second: " << int (second.size()) << '\n';std::cout << "Size of third: " << int (third.size()) << '\n';return 0;
}
4、std::deque::emplace(C++11)
template <class... Args>iterator emplace (const_iterator position, Args&&... args);
4.1参数
参数 | |
---|---|
position | 迭代器类型,位置,就在迭代器为位置插入 |
args | 用于构造新元素的参数。 |
4.2返回值
返回新插入元素的位置迭代器。
4.3功能
在位置position插入args,其余元素“后移”
// deque::emplace
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque = {10,20,30};auto it = mydeque.emplace ( mydeque.begin()+1, 100 );mydeque.emplace ( it, 200 );mydeque.emplace ( mydeque.end(), 300 );std::cout << "mydeque contains:";for (auto& x: mydeque)std::cout << ' ' << x;std::cout << '\n';return 0;
}
5、std::deque::emplace_back、std::deque::emplace_front
template <class... Args>void emplace_back (Args&&... args);template <class... Args>void emplace_front (Args&&... args);
5.1参数
参数 | |
---|---|
args | 用于构造新元素的参数。 |
5.2功能
分别在头部与尾部插入新元素args;
5.3返回值无
// deque::emplace_from
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque = {10,20,30};mydeque.emplace_back (100);mydeque.emplace_back (200);std::cout << "mydeque contains:";for (auto& x: mydeque)std::cout << ' ' << x;std::cout << '\n';return 0;
}
6、std::deque::erase
iterator erase (const_iterator position );
iterator erase (const_iterator first, const_iterator last );
删除指定位置迭代器的元素,或者删除范围内位置迭代器元素[first,last),包头去尾(包含first,不包括last);
6.1参数
(范围)位置迭代器
6.2返回值
返回新位置的迭代器
// erasing from deque
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque;// set some values (from 1 to 10)for (int i=1; i<=10; i++) mydeque.push_back(i);// erase the 6th elementmydeque.erase (mydeque.begin()+5);// erase the first 3 elements:mydeque.erase (mydeque.begin(),mydeque.begin()+3);std::cout << "mydeque contains:";for (std::deque<int>::iterator it = mydeque.begin(); it!=mydeque.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
7、std::deque::front
reference front();
const_reference front() const;
7.1功能
功能返回指向第一个元素的引用
7.2返回值
指向第一个元素的引用,如果deque被const修饰,则返回const_reference,无法修改val
// deque::front
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque;mydeque.push_front(77);mydeque.push_back(20);mydeque.front() -= mydeque.back();std::cout << "mydeque.front() is now " << mydeque.front() << '\n';return 0;
}
8、std::deque::get_allocator
9、std::deque::insert
single element (1) |
iterator insert (const_iterator position, const value_type& val);
|
---|---|
fill (2) |
iterator insert (const_iterator position, size_type n, const value_type& val);
|
range (3) |
template <class InputIterator> iterator insert (const_iterator position, InputIterator first, InputIterator last);
|
move (4) |
iterator insert (const_iterator position, value_type&& val);
|
initializer list (5) |
iterator insert (const_iterator position, initializer_list<value_type> il);
|
参数 | 功能 | |
---|---|---|
single element (1) |
position val |
在迭代器position插入val,原来元素往后“移动” |
fill (2) |
position n val |
在迭代器position插入n个val,原来元素往后“移动” |
range (3) |
position first last |
在迭代器position插入std::deque的[first,last),原来元素往后“移动” |
move (4) |
position val |
val为右值引用,把右值插入双向队列(这是我的理解,欢迎批评指正) |
initializer list (5) |
position il |
在迭代器position插入列表元素,原来元素往后“移动” |
9.1返回值
指向第一个新插入元素位置的迭代器
// inserting into a deque
#include <iostream>
#include <deque>
#include <vector>int main ()
{std::deque<int> mydeque;// set some initial values:for (int i=1; i<6; i++) mydeque.push_back(i); // 1 2 3 4 5std::deque<int>::iterator it = mydeque.begin();++it;it = mydeque.insert (it,10); // 1 10 2 3 4 5// "it" now points to the newly inserted 10mydeque.insert (it,2,20); // 1 20 20 10 2 3 4 5// "it" no longer valid!it = mydeque.begin()+2;std::vector<int> myvector (2,30);mydeque.insert (it,myvector.begin(),myvector.end());// 1 20 30 30 20 10 2 3 4 5std::cout << "mydeque contains:";for (it=mydeque.begin(); it!=mydeque.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
10、std::deque::max_size
size_type max_size() const noexcept;
返回容器可以达到的最大潜在大小,但容器绝不能保证能够达到该大小
// deque::max_size
#include <iostream>
#include <deque>int main ()
{unsigned int i;std::deque<int> mydeque;std::cout << "Enter number of elements: ";std::cin >> i;if (i<mydeque.max_size()) mydeque.resize(i);else std::cout << "That size exceeds the limit.\n";return 0;
}
11、std::deque::operator=
copy (1) |
deque& operator= (const deque& x);
|
---|---|
move (2) |
deque& operator= (deque&& x);
|
initializer list (3) |
deque& operator= (initializer_list<value_type> il);
|
copy (1) 将x的所有元素复制到容器中(x保留其内容)。
move (2) 将 x 元素移动到容器中(x 处于未指定但有效的状态)。
initializer list (3) 将 列表il 元素复制到容器中。
11.1返回值
*this
// assignment operator with deques
#include <iostream>
#include <deque>int main ()
{std::deque<int> first (3); // deque with 3 zero-initialized intsstd::deque<int> second (5); // deque with 5 zero-initialized intssecond = first;first = std::deque<int>();std::cout << "Size of first: " << int (first.size()) << '\n';std::cout << "Size of second: " << int (second.size()) << '\n';return 0;
}
12、std::deque::operator[]
reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
见这篇文章,含义一样C++_STL——array(C++11)
13、std::deque::pop_back、pop_front、push_back、push_front
功能从尾部弹出,头部弹出,尾部添加、头部添加元素
pop_back、pop_front无参数,无返回值
push_back、push_front参数const value_type& val,value_type&& val(右值引用)
// deque::pop_back
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque;int sum (0);mydeque.push_back (10);mydeque.push_back (20);mydeque.push_back (30);while (!mydeque.empty()){sum+=mydeque.back();mydeque.pop_back();}std::cout << "The elements of mydeque add up to " << sum << '\n';return 0;
}
14、std::deque::resize
void resize (size_type n);
void resize (size_type n, const value_type& val);
调整容器的大小,使其包含n个元素。
如果n小于当前容器的大小,则内容将减少到其前n个元素,删除超出的元素(并销毁它们)。
如果n大于当前容器大小,则通过在末尾插入所需数量的元素来扩展内容,以达到n的大小。如果指定了val,新元素将被初始化为val的副本,否则,它们将被值初始化。
请注意,此函数通过插入或删除容器中的元素来更改容器的实际内容。
14.1返回值
无
// resizing deque
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque;std::deque<int>::iterator it;// set some initial content:for (int i=1; i<10; ++i) mydeque.push_back(i);mydeque.resize(5);mydeque.resize(8,100);mydeque.resize(12);std::cout << "mydeque contains:";for (std::deque<int>::iterator it = mydeque.begin(); it != mydeque.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
15、std::deque::shrink_to_fit
void shrink_to_fit();
请求容器减少内存使用以适应其大小。
deque容器分配的内存可能多于容纳当前元素所需的内存:这是因为大多数库将deque实现为一个动态数组,它可以保留已删除元素的分配空间,或者预先分配额外的容量以允许更快的插入操作。
此函数要求将内存使用情况调整为容器的当前大小,但请求是非绑定的,否则容器实现可以自由优化其内存使用情况。
请注意,此函数不会更改容器的大小(请参阅)
无参数无返回值
// deque::shrink_to_fit
#include <iostream>
#include <deque>int main ()
{std::deque<int> mydeque (100);std::cout << "1. size of mydeque: " << mydeque.size() << '\n';mydeque.resize(10);std::cout << "2. size of mydeque: " << mydeque.size() << '\n';mydeque.shrink_to_fit();return 0;
}
16、std::deque::size、std::deque::swap
size_type size() const noexcept;
void swap (deque& x);
见这篇文章,含义一样C++_STL——array(C++11)
non-member overloads
std::relational operators (deque)、std::swap (deque)
见这篇文章,含义一样C++_STL——array(C++11)
vector(这里只说与deque不一样的部分)
template < class T, class Alloc = allocator<T> > class vector; // generic template
就像数组一样,vector为它们的元素使用连续的存储位置,这意味着它们的元素也可以使用指向其元素的常规指针上的偏移量来访问,并且与在数组中一样有效。但与数组不同的是,它们的大小可以动态变化,它们的存储由容器自动处理。
在内部,vector使用动态分配的数组来存储它们的元素。这个数组可能需要重新分配,以便在插入新元素时增加大小,这意味着分配一个新数组并将所有元素移动到它。就处理时间而言,这是一项相对昂贵的任务,因此,每次将元素添加到容器时,vector都不会重新分配。
相反,矢量容器可能会分配一些额外的存储空间以适应可能的增长,因此容器的实际容量可能大于严格需要包含其元素的存储空间(即其大小)。库可以实施不同的增长策略来平衡内存使用和重新分配,但在任何情况下,重新分配应该只发生在对数增长的大小间隔,以便在向量末尾插入单个元素可以提供摊销的常数时间复杂性(参见 push_back)。
因此,与数组相比,vectors 消耗更多内存以换取以高效方式管理存储和动态增长的能力。
与其他动态序列容器(deques、lists 和 forward_lists)相比,vectors 非常高效地访问其元素(就像数组一样)并且相对高效地从其末尾添加或删除元素。对于涉及在末尾以外的位置插入或删除元素的操作,它们的性能比其他操作差,并且迭代器和引用的一致性不如列表和 forward_lists。
vector在尾部插入元素时如果底层内存大小不够则底层以当前已有内存的二倍增长内存,所以很耗内存
参数
T:元素类型
Alloc:用于定义存储分配模型的分配器对象的类型。 默认情况下使用分配器类模板,它定义了最简单的内存分配模型,并且与值无关。
容器特点
序列:序列容器中的元素以严格的线性顺序排列。 单个元素按其在此序列中的位置进行访问。
动态数组:通常作为动态数组实现,它允许直接访问序列中的任何元素,并在序列的开头或结尾提供相对快速的元素添加/删除。
动态分配: 容器使用分配器对象来动态处理其存储需求。
1、std::vector::data
value_type* data() noexcept;
const value_type* data() const noexcept;
1.1功能
返回指向向量内部使用的内存数组的直接指针(头部指针,即可以说是数组名),以存储其拥有的元素。
因为向量中的元素保证按照向量所表示的相同顺序存储在连续的存储位置中,所以检索到的指针可以偏移以访问数组中的任何元素。
1.2返回值
指向向量内部使用的数组中第一个元素的指针。如果向量对象是 const 限定的,则该函数返回一个指向 const value_type 的指针。 否则,它返回一个指向 value_type 的指针。
// vector::data
#include <iostream>
#include <vector>int main ()
{std::vector<int> myvector (5);int* p = myvector.data();*p = 10;++p;*p = 20;p[2] = 100;std::cout << "myvector contains:";for (unsigned i=0; i<myvector.size(); ++i)std::cout << ' ' << myvector[i];std::cout << '\n';return 0;
}
2、不同点所有在deque的头插在这里都没有
参考:vector
deque
C++_STL——deque and vector相关推荐
- 【数据结构与算法】5. C++中 list、deque、vector对比
C++中list.deque以及vector对比 C++的容器类包括两大类: 1.顺序存储结构,包括vector.list.deque等等: 2.关联存储结构,包括set.map.multiset等等 ...
- deque与vector的主要区别
deque与vector非常相似.它也采用动态数组管理元素,提供随机存取,有着和vector几乎一样的接口.不同的是deque的动态数组头尾都开放,因此能在头尾两端进行快速安插和删除. deque通常 ...
- C++_STL标准库——容器
C++_STL标准库--容器 参考:cplusplus.com - The C++ Resources Network,VC2019,<C++primer>,<侯捷泛化编程与标准库& ...
- STL vector list deque区别与实现
1 vector 向量 相当于一个数组 在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacitu ...
- STL的Vector, List and Deque
stl提供了三个最基本的容器:vector,list,deque. vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此 它能非常好的支持随即存取,即[]操作符,但 ...
- C++:STL之vector,deque对比
为什么80%的码农都做不了架构师?>>> 之所以专门把STL中的这两个拿出来说一说,是因为vector和deque都是支持随机访问的,其支持的迭代器类型都为随机访问,而不像ma ...
- c++ vector 先进先出_STL从0开始
容器(Containers) 顺序容器 array [c++11] vector 单开口,预留空间 emplace_back[c++11] 在最后构造并插入 list 容器适配器 stack 后进先出 ...
- vector, list, deque的选用
如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面 的原则: 1.如果你需要高效的随机存取,而不在乎插入和删除的效率,使用vector 2.如果你需要大量的插入和删除,而不关心随机 ...
- 【C++ STL学习笔记】C++ STL序列式容器(array,vector,deque,list)
文章目录 C++ STL容器是什么? 迭代器是什么,C++ STL迭代器(iterator)用法详解 迭代器类别 迭代器的定义方式 C++序列式容器(STL序列式容器)是什么 容器中常见的函数成员 C ...
最新文章
- Visual Studio 2012/2010/2008 远程调试
- 20145129 课程总结
- ArrayList 集合
- 多线程一定比单线程快吗
- C++阶段01笔记05【数组(概述、一维数组、二维数组)】
- Linux 驱动开发之内核模块开发 (三)—— 模块传参
- ReflectedSchemas应该定期清理否则会占用大量C盘空间
- 关于javaweb地址栏技巧
- Linux 设置 LD_LIBRARY_PATH
- 知乎面试官:为什么不建议在 MySQL 中使用 UTF-8?
- 腾讯的bugly的更新和热更新
- Windows平板 区分当前是鼠标点击还是触摸
- 入门图形学:ComputeShader
- mac os x 使用教程_如何在Mac OS X计算机上使用扫描仪
- GDB调试器源代码分析系列--Inferior call的实现与分析(1)
- 一次jdk1.7升级jdk1.8后导致redis运行时blocked_clients过多问题解决
- 4.6 定位解算和1PPS时标支持
- eclipse配置环境变量 win10
- TM1668兼用VK1668 SOP24/SSOP24 应用于VCR.DVD 等产品的显示驱动
- 沪深A股分析数据机构持股信息API接口(JSON标准格式,Get请求方式)
热门文章
- R语言绘制堆叠条形图
- 临床基因组学数据分析实战助力解析Case,快速发表文章
- ISME:污水厂抗性组受细菌组成和基因交换驱动且出水中抗性表达活跃(一作解读)
- 中国科学:中科院遗传发育所揭示拟南芥二半萜对根系微生物组的调控机制
- seaborn将图例放置在图像外部并使用move_legend函数将图例(legend)放置在图像的底部(bottom)、且单行展开显示
- python使用fpdf生成pdf文件章节(chapter),包含:页眉、页脚、章节主题、数据排版等;
- 数据管理、数据治理、数据管控的概念区别和范围是什么?
- ModuleNotFoundError: No module named ‘pandas.rpy‘
- python保存内容到文件(text、json、csv)
- 核磁共振影像数据处理-3-DTI基础、Li‘s have a solution and plan.