一、容器库概述
1、容器内元素的类型约束
使用 C++ 标准库容器存储元素时,对于元素类型有一些要求:
- 元素类型必须支持复制语义,即可以使用赋值运算符(=)将一个元素赋值给另一个元素,这是因为标准库容器需要在内部存储和复制元素。
- 元素类型必须支持等价性,即可以使用等价比较运算符(==)比较两个元素是否相等,这是因为标准库容器需要支持查找和删除元素等操作。
- 对于不同的标准库容器,元素类型要求也不尽相同。例如,std::vector 和 std::deque 都是动态数组,但 std::vector 支持随机访问,而 std::deque 支持在队列首尾进行 O(1) 操作。因此,在使用容器时需要根据具体的需求来选择适当的容器类型。 总的来说,如果您的元素类型支持复制语义和等价性,那么它就可以作为标准库容器的元素类型。如果您的元素类型不支持复制语义和等价性,那么您可以使用 C++ 指针或其他技巧来将它存储在容器
2、容器操作
容器的操作分成三类:
- 所有容器都提供的操作
- 按照顺序容器,关联容器,无序容器分类,分别提供不同的操作
- 一小部分容器提供的操作
⚠️ 随后的表格中,列出了所有顺序容器的操作,某些不提供这些操作的容器,在表后有说明!
2.1 类型别名
操作 | 解释 |
---|---|
iterator |
此容器类型的迭代器类型 |
const_iterator |
可以读取元素但不能修改元素的迭代器类型 |
size_type |
无符号整数类型,足够保存此种容器类型最大可能的大小 |
difference_type |
带符号整数类型,足够保存两个迭代器之间的距离 |
value_type |
元素类型 |
reference |
元素的左值类型;和value_type & 含义相同 |
const_reference |
元素的const 左值类型,即const value_type & |
2.2 构造函数
操作 | 解释 |
---|---|
C c; |
默认构造函数,构造空容器 |
C c1(c2); 或C c1 = c2; |
构造c2 的拷贝c1 |
C c(b, e) |
构造c ,将迭代器b 和e 指定范围内的所有元素拷贝到c |
C c{a, b, c...} |
列表初始化c |
- 只有顺序容器的构造函数才接受大小参数,关联容器并不支持。
array
具有固定大小。- 和其他容器不同,默认构造的
array
是非空的。 array
可以拷贝和对象赋值 , 这一点与内置数组不同- 直接复制:将一个容器复制给另一个容器时,类型必须匹配:容器类型和元素类型都必须相同。
- 使用迭代器复制:不要求容器类型相同,容器内的元素类型也可以不同。
2.3 赋值和swap
操作 | 解释 |
---|---|
c1 = c2; |
将c1 中的元素替换成c2 中的元素 |
c1 = {a, b, c...} |
将c1 中的元素替换成列表中的元素(不适用于array ) |
c1.swap(c2) |
交换c1 和c2 的元素 |
swap(c1, c2) |
等价于c1.swap(c2) |
c.assign(b, e) |
将c 中的元素替换成迭代器b 和e 表示范围中的元素,b 和e 不能指向c 中的元素 |
c.assign(il) |
将c 中的元素替换成初始化列表il 中的元素 |
c.assign(n, r) |
将c 中的元素替换为n 个值是t 的元素 |
2.3.1 赋值
-
赋值左右大小若不一致,则两边都和右边一致
-
[[顺序容器#4.3 array的拷贝与对象赋值| array赋值操作]]
-
使用非成员版本的
swap
是一个好习惯。swap
不会导致容器的指针,迭代器,引用,失效, 他们仍然指向或者引用之前所指向或引用的那些元素,但是已经属于不同的容器了 -
assign
操作不适用于关联容器和array
2.3.2 使用assign (仅顺序容器)
顺序容器(array除外)还定义了一个名为assign的成员, 允许我们从一个不同但相容的类型赋值,或者从容器的一个子序列赋值,只要能转换
|
|
2.3.3 使用swap
swap操作交换两个相同类型容器的内容。调用swap之后,两个容器中的元素将会交换;
|
|
交换两个容器内容的操作保证会很快—— 元素本身并未交换,swap只是交换了两个 容器的内部数据结构
除 array外,swap不对任何元素进行拷贝、删除或插入操作,因此可以保证生 在常数时间内完成,但是array会真正的交换
这也意味着,指向容器的迭代器、引用和指针在swap操作之后不会失效,仍旧指向之前的元素
例如:假定iter在 swap之前指向svec1 [3]
的string,那么在swap之后它指向svec2 [3]
的元素
2.4 大小
操作 | 解释 |
---|---|
c.size() |
c 中元素的数目(不支持forward_list ) |
c.max_size() |
c 中可保存的最大元素数目 |
c.empty() |
若c 中存储了元素,返回false ,否则返回true |
2.5 添加元素/删除元素
操作 | 解释 |
---|---|
c.insert(args) |
将args 中的元素拷贝进c |
c.emplace(init) |
使用inits 构造c 中的一个元素 |
c.erase (args) |
删除args 指定的元素 |
c.clear() |
删除c 中的所有元素,返回void |
2.6 获取迭代器
操作 | 解释 |
---|---|
c.begin() , c.end() |
返回指向c 的首元素和尾元素之后位置的迭代器 |
c.cbegin() , c.cend() |
返回const_iterator |
- 以
c
开头的版本是C++11新标准引入的 - 当不需要写访问时,应该使用
cbegin
和cend
。
2.7 反向容器的额外成员
操作 | 解释 |
---|---|
reverse_iterator |
按逆序寻址元素的迭代器 |
const_reverse_iterator |
不能修改元素的逆序迭代器 |
c.rbegin() , c.rend() |
返回指向c 的尾元素和首元素之前位置的迭代器 |
c.crbegin() , c.crend() |
返回const_reverse_iterator |
- 不支持
forward_list
2.8 关系运算符
操作 | 解释 |
---|---|
== != |
所有容器都支持相等(不等)运算符 |
< , < = , > , > = |
关系运算符(无序关联容器不支持) |
关系运算符左右两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素,比较两个容器实际上是进行元素的逐对比较 |
graph LR
s[比较]
s-->c_1[不相等:元素个数不同]
s-->c_2[相等:元素个数和元素大小都相等]
c_1-->c_2_1[存在包含关系,比个数]
c_1-->c_2_2[有交集不包含,比较第一个不等的元素]
所谓元素的大小:容器的关系运算符使用元素的关系运算符完成比较
2.9 迭代器
什么是迭代器? 在 C++ 中,迭代器是一个对象,它提供了在容器(如数组、链表等)中遍历元素的方法。通俗地说,迭代器就像是容器中的一个指针,可以通过迭代器来访问容器中的元素,比如获取、修改、插入元素等。 C++ 中的迭代器类型分为五种:输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。每种类型的迭代器都有不同的功能和性能,例如,随机访问迭代器支持 O(1) 的随机访问,而输入迭代器仅支持递增的遍历。 使用迭代器的好处是,它可以使代码变得更加简洁和可移植,因为迭代器抽象了对容器的遍历,从而使得代码对容器的具体实现细节更加独立。
- forward_list , list 不支持迭代器的算数运算
- 迭代器范围:
begin
到end
,即第一个元素到最后一个元素的后面一个位置。 - 左闭合区间:
[begin, end)
- 左闭合范围蕴含的编程设定:
- 如果
begin
和end
相等,则范围为空。 - 如果二者不等,则范围至少包含一个元素,且
begin
指向该范围中的第一个元素。 - 可以对
begin
递增若干次,使得begin == end
。
- 如果
2.10 容器定义和初始化
![[Pasted image 20230211004318.png]]
2.10.1 利用拷贝初始化
1. 拷贝整个容器 两个容器的类型及其元素类型必须匹配
2. 拷贝由一个迭代器对指定的元素范围 当传递迭代器参数来拷贝一个范围时,就不要求容器类型是相同的了。而且,新容器和原容器中的元素类型也可以不同,只要能将要拷贝的元素转换 为要初始化的容器的元素类型即可
|
|
2.10.2 列表初始化
|
|
对于除array之外的容器类型, 初始化列表还隐含地指定了容器的大小:容器将包含与初始值一样多的元素
2.10.3 顺序容器特有的构造函数
除了与关联容器相同的构造函数外,顺序容器(array除外)还提供另一个构造函数, 它接受一个容器大小和一个(可选的)元素初始值。如果我们不提供元素初始值,则标准库会创建一个值初始化器
|
|
如果元素类型是类类型,只有当该类有默认构造函数才能不指定初始值,否则必须显示初始化
二、顺序容器
顺序容器(sequential container):顺序容器都提供了快速顺序访问元素的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。
1、顺序容器类型
容器类型 | 介绍 |
---|---|
vector |
可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢。 |
deque |
双端队列。支持快速随机访问。在头尾位置插入/删除速度很快。 |
list |
双向链表。只支持双向顺序访问。在list 中任何位置进行插入/删除操作速度都很快。 |
forward_list |
单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快。 |
array |
固定大小数组。支持快速随机访问。不能添加或者删除元素。 |
string |
与vector 相似的容器,但专门用于保存字符。随机访问块。在尾部插入/删除速度快。 |
- 除了固定大小的
array
外,其他容器都提供高效、灵活的内存管理。 forward_list
和array
是新C++标准增加的类型。- 通常使用
vector
是最好的选择,除非你有很好的理由选择其他容器。 - 每个容器都定义在一个头文件中,文件名与类型名相同,容器均定义为模板类,按照[[模板与泛型编程|模板]]的使用规则来使用
- 新标准库的容器比旧版的快得多。
2、顺序容器操作
2.1 添加元素
操作 | 解释 |
---|---|
c.push_back(t) |
在c 尾部创建一个值为t 的元素,返回void |
c.emplace_back(args) |
同上 |
c.push_front(t) |
在c 头部创建一个值为t 的元素,返回void |
c.emplace_front(args) |
同上 |
c.insert(p, t) |
在迭代器p 指向的元素之前创建一个值是t 的元素,返回指向新元素的迭代器 |
c.emplace(p, args) |
同上 |
c.insert(p, n, t) |
在迭代器p 指向的元素之前插入n 个值为t 的元素,返回指向第一个新元素的迭代器;如果n 是0,则返回p |
c.insert(p, b, e) |
将迭代器b 和e 范围内的元素,插入到p 指向的元素之前;如果范围为空,则返回p |
c.insert(p, il) |
il 是一个花括号包围中的元素值列表,将其插入到p 指向的元素之前;如果il 是空,则返回p |
-
因为这些操作会改变大小,因此不适用于
array
。 -
forward_list
有自己专有版本的insert
和emplace
。 -
forward_list
不支持push_back
和emplace_back
。 -
vector
和string
不支持push_front
和emplace_front
-
当我们用一个对象去初始化容器或者将对象插入到容器时,实际上放入的是对象的拷贝。
-
emplace
开头的函数是新标准引入的,这些操作是构造而不是拷贝元素。将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素
|
|
- 传递给
emplace
的参数必须和元素类型的构造函数相匹配。
2.2 访问元素
操作 | 解释 |
---|---|
c.back() |
返回c 中尾元素的引用。若c 为空,函数行为未定义 |
c.front() |
返回c 中头元素的引用。若c 为空,函数行为未定义 |
c[n] |
返回c 中下标是n 的元素的引用,n 时候一个无符号证书。若n>=c.size() ,则函数行为未定义 |
c.at(n) |
返回下标为n 的元素引用。如果下标越界,则抛出out_of_range 异常 |
- 访问成员函数返回的是引用。
at
和下标操作只适用于string
、vector
、deque
、array
。back
不适用于forward_list
。- 如果希望下标是合法的,可以使用
at
函数。
2.3 删除元素
操作 | 解释 |
---|---|
c.pop_back() |
删除c 中尾元素,若c 为空,则函数行为未定义。函数返回void |
c.pop_front() |
删除c 中首元素,若c 为空,则函数行为未定义。函数返回void |
c.erase(p) |
删除迭代器p 指向的元素,返回一个指向被删除元素之后的元素的迭代器,若p 本身是尾后迭代器,则函数行为未定义 |
c.erase(b, e) |
删除迭代器b 和e 范围内的元素,返回指向最后一个被删元素之后元素的迭代器,若e 本身就是尾后迭代器,则返回尾后迭代器 |
c.clear() |
删除c 中所有元素,返回void |
- 会改变容器大小,不适用于
array
。 forward_list
有特殊版本的erase
forward_list
不支持pop_back
vector
和string
不支持pop_front
2.4 特殊的forward_list操作
- 链表在删除元素时需要修改前置节点的内容,双向链表会前驱的指针,但是单向链表没有保存,因此需要增加获取前置节点的方法。
forward_list
定义了before_begin
,即首前(off-the-begining)迭代器,允许我们再在首元素之前添加或删除元素。
操作 | 解释 |
---|---|
lst.before_begin() |
返回指向链表首元素之前不存在的元素的迭代器,此迭代器不能解引用。 |
lst.cbefore_begin() |
同上,但是返回的是常量迭代器。 |
lst.insert_after(p, t) |
在迭代器p 之后插入元素。t 是一个对象 |
lst.insert_after(p, n, t) |
在迭代器p 之后插入元素。t 是一个对象,n 是数量。若n 是0则函数行为未定义 |
lst.insert_after(p, b, e) |
在迭代器p 之后插入元素。由迭代器b 和e 指定范围。 |
lst.insert_after(p, il) |
在迭代器p 之后插入元素。由il 指定初始化列表。 |
emplace_after(p, args) |
使用args 在p 之后的位置,创建一个元素,返回一个指向这个新元素的迭代器。若p 为尾后迭代器,则函数行为未定义。 |
lst.erase_after(p) |
删除p 指向位置之后的元素,返回一个指向被删元素之后的元素的迭代器,若p 指向lst 的尾元素或者是一个尾后迭代器,则函数行为未定义。 |
lst.erase_after(b, e) |
类似上面,删除对象换成从b 到e 指定的范围。 |
2.5 改变容器的大小
操作 | 解释 |
---|---|
c.resize(n) |
调整c 的大小为n 个元素,若n<c.size() ,则多出的元素被丢弃。若必须添加新元素,对新元素进行值初始化 |
c.resize(n, t) |
调整c 的大小为n 个元素,任何新添加的元素都初始化为值t |
resize
不适用与array
3、容器操作可能使迭代器失效
- 在向容器添加元素后:
- 如果容器是
vector
或string
,且存储空间被重新分配,则指向容器的迭代器、指针、引用都会失效。 - 对于
deque
,插入到除首尾位置之外的任何位置都会导致指向容器的迭代器、指针、引用失效。如果在首尾位置添加元素,迭代器会失效,但指向存在元素的引用和指针不会失效。 - 对于
list
和forward_list
,指向容器的迭代器、指针和引用依然有效。
- 如果容器是
- 在从一个容器中删除元素后:
- 对于
list
和forward_list
,指向容器其他位置的迭代器、引用和指针仍然有效。 - 对于
deque
,如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器、指针、引用都会失效;如果是删除deque
的尾元素,则尾后迭代器会失效,但其他不受影响;如果删除的是deque
的头元素,这些也不会受影响。 - 对于
vector
和string
,指向被删元素之前的迭代器、引用、指针仍然有效。 - 注意:当我们删除元素时,尾后迭代器总是会失效。
- 注意:使用失效的迭代器、指针、引用是严重的运行时错误!
- 建议:将要求迭代器必须保持有效的程序片段最小化。
- 建议:不要保存
end
返回的迭代器。
- 对于
4、array
4.1 array 定义
与内置数组一样,标准库array的大小也是类型的一部分。当定义一个array时, 除了指定元素类型,还要指定容器大小
|
|
4.2 array 初始化
4.2.1 默认初始化
array默认初始化包含和定义中一样多的元素,元素的值都被默认初始化,而非空,这一点与其他顺序容器不同
4.2.2 列表初始化
如果我们对array进行列表初始化,初始值的数目必须等于或小于array的大小 如果元素类型是类类型,那么就一定要有可以值初始化的构造函数
4.3 array的拷贝与对象赋值
array不同于内置数组类型,可以拷贝或对象赋值
|
|
两个限制:1.初始值类型一致 ; 2.大小必须一样
三、vector对象是如何增长的
vector
和string
在内存中是连续保存的,如果原先分配的内存位置已经使用完,则需要重新分配新空间,将已有元素从就位置移动到新空间中,然后添加新元素。
vector是如何扩容的 当不得不获取新的内存空间时,vector和 string的实现通常会分配比新的空间需求更大 的内存空间。容器预留这些空间作为备用,可用来保存更多的新元素。这样,就不需要每次添加新元素都重新分配容器的内存空间了。
管理容量的成员函数 vector和 string类型提供了一些成员函数,允许我们与它的实现中内存分配部分互动
操作 | 解释 |
---|---|
c.shrink_to_fit() |
将capacity() 减少到和size() 相同大小 |
c.capacity() |
不重新分配内存空间的话,c 可以保存多少个元素 |
c.reverse(n) |
分配至少能容纳n 个元素的内存空间 |
shrink_to_fit
只适用于vector
、string
和deque
capacity
和reverse
只适用于vector
和string
。
|
|
总结一哈 只要size不超过capacity就不重新分配,reserve可以要求每次扩容,不少于reserve的实参,但是如果实参也满足不了,就会超过这个值,shrink_to_fit只是一个请求,并非一定会执行
四、额外的string操作
1、构造string的其他方法
^5f2418
操作 | 解释 |
---|---|
string s(cp, n) |
s 是cp 指向的数组中前n 个字符的拷贝,此数组 |
string s(s2, pos2) |
s 是string s2 从下标pos2 开始的字符的拷贝。若pos2 > s2.size() ,则构造函数的行为未定义。 |
string s(s2, pos2, len2) |
s 是string s2 从下标pos2 开始的len2 个字符的拷贝。 |
n
,len2
,pos2
都是无符号值- 这些构造函数接受
const char*
和string
参数 , 当从const char *
创建string
时,这样的数组必须以空字符结尾拷贝,操作遇到空字符时停止,如果我们还给构造函数一个计数值,数组就不必以空字符结尾。
substr操作
操作 | 解释 |
---|---|
s.substr(pos, n) |
返回一个string ,包含s 中从pos 开始的n 个字符的拷贝。pos 的默认值是0,n 的默认值是s.size() - pos ,即拷贝从pos 开始的所有字符。 |
2、改变string的其他方法
操作 | 解释 |
---|---|
s.insert(pos, args) |
在pos 之前插入args 指定的字符。pos 可以使是下标或者迭代器。接受下标的版本返回指向s 的引用;接受迭代器的版本返回指向第一个插入字符的迭代器。 |
s.erase(pos, len) |
删除从pos 开始的len 个字符,如果len 被省略,则删除后面所有字符,返回指向s 的引用。 |
s.assign(args) |
将s 中的字符替换成args 指定的字符。返回一个指向s 的引用。 |
s.append(args) |
将args 指定的字符追加到s ,返回一个指向s 的引用。 |
s.replace(range, args) |
删除s 中范围range 中的字符,替换成args 指定的字符。返回一个指向s 的引用。 |
3、string搜索操作
string
类提供了6个不同的搜索函数,每个函数都有4个重载版本。- 每个搜索操作都返回一个
string::size_type
值,表示匹配发生位置的下标。如果搜索失败则返回一个名为string::npos
的static
成员(类型是string::size_type
,初始化值是-1,也就是string
最大的可能大小)。
搜索操作 | 解释 |
---|---|
s.find(args) |
查找s 中args 第一次出现的位置 |
s.rfind(args) |
查找s 中args 最后一次出现的位置 |
s.find_first_of(args) |
在s 中查找args 中任何一个字符第一次出现的位置 |
s.find_last_of(args) |
在s 中查找args 中任何一个字符最后一次出现的位置 |
s.find_first_not_of(args) |
在s 中查找第一个不在args 中的字符 |
s.find_first_not_of(args) |
在s 中查找最后一个不在args 中的字符 |
args必须是一下的形式之一:
args 形式 |
解释 |
---|---|
c, pos |
从s 中位置pos 开始查找字符c 。pos 默认是0 |
s2, pos |
从s 中位置pos 开始查找字符串s 。pos 默认是0 |
cp, pos |
从s 中位置pos 开始查找指针cp 指向的以空字符结尾的C风格字符串。pos 默认是0 |
cp, pos, n |
从s 中位置pos 开始查找指针cp 指向的前n 个字符。pos 和n 无默认值。 |
4、compare函数
逻辑类似于C标准库的strcmp
函数,根据s
是等于、大于还是小于参数指定的字符串,s.compare
返回0、正数或负数。
s.compare()
的几种参数形式
参数形式 | 解释 |
---|---|
s2 |
比较s 和s2 |
pos1, n1, s2 |
比较s 从pos1 开始的n1 个字符和s2 |
pos1, n1, s2, pos2, n2 |
比较s 从pos1 开始的n1 个字符和s2 |
cp |
比较s 和cp 指向的以空字符结尾的字符数组 |
pos1, n1, cp |
比较s 从pos1 开始的n1 个字符和cp 指向的以空字符结尾的字符数组 |
pos1, n1, cp, n2 |
比较s 从pos1 开始的n1 个字符和cp 指向的地址开始n2 个字符 |
5、string和数值转换
转换 | 解释 |
---|---|
to_string(val) |
一组重载函数,返回数值val 的string 表示。val 可以使任何算术类型。对每个浮点类型和int 或更大的整型,都有相应版本的to_string() 。和往常一样,小整型会被提升。 |
stoi(s, p, b) |
返回s 起始子串(表示整数内容)的数值,p 是s 中第一个非数值字符的下标,默认是0,b 是转换所用的基数。返回int |
stol(s, p, b) |
返回long |
stoul(s, p, b) |
返回unsigned long |
stoll(s, p, b) |
返回long long |
stoull(s, p, b) |
返回unsigned long long |
stof(s, p) |
返回s 起始子串(表示浮点数内容)的数值,p 是s 中第一个非数值字符的下标,默认是0。返回float |
stod(s, p) |
返回double |
stold(s, p) |
返回long double |
五、容器适配器(adapter)
1、什么是适配器
C++ 中的适配器是指一种对标准库容器或其他数据结构进行包装或修饰的结构,以提供不同的接口或行为。适配器在 C++ 中被广泛用于容器库中,可以简化程序代码,提高代码可读性和可维护性。 C++ 标准库提供了以下几种适配器:
- std::stack:使用底层容器作为栈,提供了一个顶部的元素访问接口,支持 push 和 pop 操作。
- std::queue:使用底层容器作为队列,提供了一个队列头部的元素访问接口,支持入队和出队操作。
- std::priority_queue:使用底层容器作为优先队列,提供了一个优先级最高的元素访问接口,支持入队和出队操作。
2、适配器的通用操作和类型
操作 | 解释 |
---|---|
size_type |
一种类型,须以保存当前类型的最大对象的大小 |
value_type |
元素类型 |
container_type |
实现适配器的底层容器类型 |
A a; |
创建一个名为a 的空适配器 |
A a(c) |
创建一个名为a 的适配器,带有容器c 的一个拷贝 |
关系运算符 | 每个适配器都支持所有关系运算符:== 、!= 、< 、 <= 、> 、>= 这些运算符返回底层容器的比较结果 |
a.empty() |
若a 包含任何元素,返回false ;否则返回true |
a.size() |
返回a 中的元素数目 |
swap(a, b) |
交换a 和b 的内容,a 和b 必须有相同类型,包括底层容器类型也必须相同 |
a.swap(b) |
同上 |
- 可以使用适配器操作,而不能使用底层容器类型的操作。
3、定义一个适配器
stack
和queue
是基于deque
实现的,priority_queue
是在vector
之上实现的,可以在创建一个适配器时将一个命名的顺序容器作为第二个类型参数,来重载默认容器类型
|
|
每个适配器都定义两个构造函数 1.默认构造函数创建一个空对象
|
|
2.接受一个容器的构造函数拷贝该容器来初始化适配器
|
|
4、stack
操作 | 解释 |
---|---|
s.pop() |
删除栈顶元素,不返回。 |
s.push(item) |
创建一个新元素,压入栈顶,该元素通过拷贝或移动item 而来 |
s.emplace(args) |
同上,但元素由args 来构造。 |
s.top() |
返回栈顶元素,不删除。 |
- 定义在
stack
头文件中。 stack
默认基于deque
实现,也可以在list
或vector
之上实现。
5、queue和priority_queue
操作 | 解释 |
---|---|
q.pop() |
删除队首元素,但不返回。 |
q.front() |
返回队首元素的值,不删除。 |
q.back() |
返回队尾元素的值,不删除。只适用于queue |
q.top() |
返回具有最高优先级的元素值,不删除。 |
q.push(item) |
在队尾压入一个新元素。 |
q.emplace(args) |
- 定义在
queue
头文件中。 queue
默认基于deque
实现,priority_queue
默认基于vector
实现。queue
可以在list
或vector
之上实现,priority_queue
也可以用deque
实现。