* * * 前言 * * *
STL(Standard Template Library)是C++标准模板库的缩写,它是C++标准库的一部分,提供了丰富的通用数据结构和算法。STL中主要包括容器(Containers)、迭代器(Iterators)、算法(Algorithms)、函数对象(Function Objects)、适配器(Adapters)等组件。其中,多种多样的容器提供了不同的数据结构,可以满足各种需求。
序列式容器是一种数据结构,用于存储和管理一系列元素,这些元素按照它们被插入的顺序进行排列。在编程中,序列式容器通常提供了对元素的有序访问和操作,例如可以按照索引值访问、插入或删除元素。
常见的序列式容器包括向量(vector)、列表(list)、双端队列(deque)、栈(stack)、队列(queue)
一、向量(vector)
1)vector的实质
在C++中,std::vector 是一个动态数组容器。
2)vector的优势
相比于普通的数组,向量vector的好处在于:可以动态调整大小,避免了数组开辟空间太大导致的浪费和数组开辟空间不足导致的不够的两大弊病;
相比于链表,向量vector的好处在于:可以像数组一样利用下标来访问元素、改变元素,极大降低了操作数据时的时间消耗和空间消耗。
3)vector声明和初始化
注意:使用向量vector操作时,需要包含vector的头文件
4)vector访问元素
边界检查:[ ] 操作符不进行边界检查,如果访问超出范围的索引,会导致未定义行为,可能引发程序崩溃或产生不可预测的结果。而 at() 方法会进行边界检查,如果访问超出范围的索引,会抛出 std::out_of_range 异常。
性能开销:由于 at() 方法进行了边界检查,因此它的执行速度相对较慢。而 [ ] 操作符没有边界检查,因此执行速度更快。
5)vector插入和删除元素
std::vector 可以根据需要动态增加或减少元素的数量,而不需要手动管理内存。
6)vector获取大小和容量
大小(Size):向量的大小表示当前实际存储的元素数量。可以通过 size() 方法来获取向量的大小,例如 vec.size()。当你向向量中添加或删除元素时,大小会相应地增加或减少。
容量(Capacity):向量的容量表示当前在分配的内存空间中可以容纳的元素数量,即向量在重新分配内存之前可以存储的元素数量。可以通过 capacity() 方法来获取向量的容量,例如 vec.capacity()。当向量的大小超过当前容量时,向量会重新分配更大的内存空间来存储更多的元素,这个过程可能导致内存的重新分配和元素的复制,因此会带来一定的性能开销。
7)检查向量是否为空
二、 列表(list)
1)list的实质
在 C++ 中,std::list 是一个双向链表容器,可以用于存储和操作元素的有序集合。
2)list的优势
与单向链表不同,双向链表使得访问元素变得可逆,因而更加灵活;
与数组或向量相比,list的元素并不是连续存储的,而是通过指针链表连接起来的,这使得插入或删除元素更加高效、简洁;而 std::vector 中间插入元素会导致插入点之后的所有元素都向后移动,这可能会造成较大的性能消耗,特别是在大规模数据操作时。
3)list声明和初始化
注意:使用列表list操作时,需要包含list的头文件
4)list遍历和访问元素
双向迭代器支持从前向后和从后向前遍历。
- 使用迭代器访问元素:
- 使用std::advance函数访问元素:
5) list插入和删除元素
指定位置仍需要通过迭代器遍历寻找,消耗较大
6) list排序
三、 双端队列(deque)
1)deque的实质
双端队列(deque,全称 double-ended queue)是 C++ 标准库中的一种容器,与向量类似,但在两端进行插入和删除操作时更为高效。
2)deque的优势
双端队列是一个非常实用的数据结构,特别适合需要在两端频繁进行插入和删除操作的场景。如果需要在两端进行高效地数据操作,并且希望能够随机访问元素,双端队列是一个很好的选择。
3)deque声明和初始化
注意:使用双端队列deque操作时,需要包含deque的头文件
4)deque访问元素
5)deque插入和删除元素
插入:
删除:
四、栈(stack)
1)stack的实质
栈(Stack)是一种遵循后进先出(Last In, First Out,LIFO)原则的数据结构。这意味着最后压入栈的元素会最先被弹出。
2)stack的优势
与其他数据结构相比,栈后进先出的特性对于特定的逆序处理的问题具有奇效,此外,栈的基本操作包括压入(push)和弹出(pop)的实现简单、高效;栈的自动的内存管理机制也非常高效。
3)stack声明和初始化
注意:使用栈stack操作时,需要包含stack的头文件
4)stack压入、弹出操作
5)stack访问元素
对于栈中非栈顶的元素,可以先将栈中的元素弹出并存储,然后再将其压回栈中。这样做可以保持栈的原始状态。
6)stack遍历
五、 队列(queue)
1)queue的实质
队列(queue)是一种具有先进先出(FIFO,First-In-First-Out)特性的线性数据结构。在队列中,元素按照其入队顺序排列,最先进入队列的元素将最先被移出。与栈(stack)恰恰相反。
2)queue的优势
队列遵循的先进先出的特性,在很多情况下非常实用,例如任务调度、消息传递等场景。队列的底层实现通常采用数组或链表等数据结构,插入和删除操作的时间复杂度为O(1),这使得队列在处理大量数据时具有较高的效率。队列的操作比较简单,主要包括入队和出队操作,使用起来非常直观和方便。
3)queue声明和初始化
注意:使用队列queue操作时,需要包含queue的头文件
4)queue入队、出队操作
与栈stack的语法相同,但因为数据结构不同,所以存入效果不同。
5)queue访问元素
对于访问随机元素,与栈stack也相似,需要进行简单遍历操作。对于队首和队尾元素可以使用现成的语句访问。
6)queue元素数量
其中第一个示例也是遍历队列的常用方式。