vector
向量(Vector)是STL中最常用的容器之一,它提供了动态数组的功能,支持随机访问和动态调整大小。下面是向量的一些基本操作:
- 创建向量:
#include <vector>
std::vector<int> vec;
// 创建一个空的整型向量
- 向向量中添加元素:
vec.push_back(10);
// 在向量末尾添加元素10
- 获取向量的大小:
int size = vec.size();
// 获取向量中元素的个数
- 访问向量中的元素:
int firstElement = vec[0];
// 访问第一个元素 int lastElement = vec.back();
// 访问最后一个元素
- 遍历向量中的元素:
for (int i = 0; i < vec.size(); ++i) { std::cout << vec[i] << " ";
}
或者使用 C++11 中的范围遍历:
for (int element : vec) { std::cout << element << " ";
}
- 删除向量中的元素:
vec.pop_back();
// 删除向量末尾的元素
- 清空向量:
vec.clear();
// 清空向量中的所有元素
这些是向量的一些基本操作,可以用来创建、添加、访问、遍历、删除和清空向量中的元素。
需要注意的是,向量支持动态调整大小,因此在需要时可以动态地添加或删除元素。
stack
栈(Stack)是一种后进先出(LIFO)的数据结构,它的基本操作包括:
- 创建栈:
#include <stack>
std::stack<int> myStack;
// 创建一个空的整数栈
- 向栈顶压入元素:
myStack.push(10);
// 将元素10压入栈顶
- 从栈顶弹出元素:
myStack.pop();
// 弹出栈顶元素(10)
- 访问栈顶元素:
int topElement = myStack.top();
// 获取栈顶元素的值(不弹出)
- 检查栈是否为空:
if (myStack.empty()) { // 栈为空 }
else { // 栈不为空 }
- 获取栈中元素的个数:
int size = myStack.size();
// 获取栈中元素的个数
栈是一种非常常见的数据结构,在许多情况下都非常有用,例如函数调用、表达式求值等。
它提供了一种后进先出的存储方式,使得最后进入栈的元素最先被访问。
queue
队列(Queue)是一种先进先出(FIFO)的容器,通常用于在数据结构中保存元素,并且按照它们进入队列的顺序进行处理。以下是队列的基本操作:
- 创建队列:
#include <queue>
std::queue<int> q;// 创建一个空的整型队列
- 向队列中添加元素:
q.push(10);
// 将元素10添加到队列末尾
- 访问队列中的元素:
由于队列是先进先出的数据结构,因此不能像向量一样直接访问任意位置的元素。只能访问队列的头部元素。
int frontElement = q.front();
// 获取队列头部的元素值,但不会删除元素
- 删除队列中的元素:
q.pop();
// 删除队列头部的元素
- 检查队列是否为空:
if (q.empty()) { // 队列为空 }
else { // 队列不为空 }
- 获取队列中的元素个数:
int size = q.size();
// 获取队列中元素的个数
队列的基本操作主要包括创建队列、添加元素、访问元素、删除元素、检查队列是否为空以及获取队列中的元素个数。
需要注意的是,队列只允许在队列的一端添加元素(尾部),在另一端删除元素(头部),并且只能访问头部的元素。
set
集合(Set)是一种关联容器,其中的元素是唯一的,并且按照一定的排序规则进行自动排序。以下是集合的基本操作:
- 创建集合:
#include <set>
std::set<int> mySet;
// 创建一个空的整数集合
- 向集合中添加元素:
mySet.insert(10);
// 向集合中插入元素10 mySet.insert(20);
// 向集合中插入元素20
- 从集合中删除元素:
mySet.erase(10);
// 从集合中删除元素10
- 检查集合中是否存在某个元素:
if (mySet.find(20) != mySet.end()) { // 集合中存在元素20 }
else { // 集合中不存在元素20 }
- 获取集合中的元素个数:
int size = mySet.size();
// 获取集合中元素的个数
- 遍历集合中的元素:
for (const auto& element : mySet) { std::cout << element << std::endl;
}
- 清空集合:
mySet.clear();
// 清空集合,使其不包含任何元素
集合中的元素是唯一的,并且按照一定的排序规则进行自动排序。因此,插入、删除和查找元素的操作都具有较高的效率。集合提供了一种方便的方式来管理一组唯一的元素。
map
映射(Map)是一种关联容器,它将键和值一一对应存储,并且根据键的排序规则自动排序。以下是映射的基本操作:
- 创建映射:
#include <map>
std::map<std::string, int> myMap;
// 创建一个空的映射,键为字符串,值为整数
- 向映射中添加键值对:
myMap["apple"] = 10;
// 向映射中添加键值对<"apple", 10> myMap["banana"] = 20;
// 向映射中添加键值对<"banana", 20>
- 访问映射中的元素:
int value = myMap["apple"];// 获取键为"apple"的值// 如果键不存在会插入一个新的键值对,值为默认值(对于整数,值为0)
- 删除映射中的元素:
myMap.erase("banana");
// 删除键为"banana"的键值对
- 检查映射中是否存在某个键:
if (myMap.find("apple") != myMap.end()) { // 存在键"apple" }
else { // 不存在键"apple" }
- 获取映射中的元素个数:
int size = myMap.size();
// 获取映射中键值对的个数
- 遍历映射中的键值对:
for (const auto& pair : myMap) { std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}
也可以使用 C++11 中的结构化绑定:
for (auto& [first, second] : myMap) { std::cout << "Key: " << first << ", Value: " << second << std::endl;
}
这些是映射的基本操作,可以用来创建映射、添加键值对、访问元素、删除元素、检查键是否存在、获取元素个数以及遍历键值对。
映射中的键值对是按照键的排序规则自动排序的。
priority_queue
优先队列(Priority Queue)是一种特殊的队列,其中的元素按照一定的优先级顺序进行排列,具有较高优先级的元素先被取出。其基本操作包括:
- 创建优先队列:
#include <queue>
std::priority_queue<int> myPriorityQueue;
// 创建一个空的整数优先队列,默认按照降序排序#include <queue>
std::priority_queue<int, vector<int>, greater<int>> myPriorityQueue;
// 创建一个空的整数优先队列,并且按照升序排序
- 向优先队列中插入元素:
myPriorityQueue.push(10);
// 插入元素10 myPriorityQueue.push(20);
// 插入元素20
- 从优先队列中取出优先级最高的元素:
int topElement = myPriorityQueue.top();
// 获取优先级最高的元素值(不弹出)
- 从优先队列中删除优先级最高的元素:
myPriorityQueue.pop();
// 弹出优先级最高的元素
- 检查优先队列是否为空:
if (myPriorityQueue.empty()) { // 优先队列为空 }
else { // 优先队列不为空 }
- 获取优先队列中元素的个数:
int size = myPriorityQueue.size();
// 获取优先队列中元素的个数
优先队列常用于需要按照优先级处理元素的场景,例如任务调度、事件处理等。
默认情况下,优先队列按照元素的值进行降序排序,但也可以通过自定义比较函数或使用自定义类型来改变排序方式。
deque
双端队列(Deque)是一种序列容器,允许在两端进行插入和删除操作。以下是双端队列的基本操作:
- 创建双端队列:
#include <deque>
std::deque<int> dq;
// 创建一个空的整型双端队列
- 向双端队列中添加元素:
dq.push_back(10);
// 在队列尾部添加元素10 dq.push_front(20);
// 在队列头部添加元素20
- 访问双端队列中的元素:
int backElement = dq.back();
// 获取队列尾部的元素值,但不会删除元素 int frontElement = dq.front();
// 获取队列头部的元素值,但不会删除元素
- 删除双端队列中的元素:
dq.pop_back();
// 删除队列尾部的元素 dq.pop_front();
// 删除队列头部的元素
- 检查双端队列是否为空:
if (dq.empty()) { // 队列为空 }
else { // 队列不为空 }
- 获取双端队列中的元素个数:
int size = dq.size();
// 获取队列中元素的个数
- 访问双端队列中的元素(随机访问):
与向量类似,双端队列也支持随机访问,可以使用索引访问队列中的元素。
int element = dq[2];
// 访问队列中索引为2的元素值
双端队列的基本操作主要包括创建队列、添加元素、访问元素、删除元素、检查队列是否为空以及获取队列中的元素个数。
与队列不同的是,双端队列允许在两端进行插入和删除操作,因此具有更灵活的使用方式。
unordered_map
unordered_map(无序映射)是C++中的一种关联容器,它提供了键值对的存储和检索,并且具有快速的查找速度。它的基本操作包括:
- 创建unordered_map:
#include <unordered_map>
std::unordered_map<std::string, int> myMap;
// 创建一个空的无序映射,键为string类型,值为int类型
- 向unordered_map中插入键值对:
myMap["apple"] = 10;
// 插入键为"apple",值为10的键值对 myMap["banana"] = 20;
// 插入键为"banana",值为20的键值对
- 从unordered_map中访问元素:
int value = myMap["apple"];
// 获取键为"apple"的值
- 检查unordered_map中是否存在某个键:
if (myMap.find("apple") != myMap.end()) { // 键"apple"存在于unordered_map中 }
else { // 键"apple"不存在于unordered_map中 }
- 删除unordered_map中的键值对:
myMap.erase("banana");
// 删除键为"banana"的键值对
- 获取unordered_map中键值对的个数:
int size = myMap.size();
// 获取unordered_map中键值对的个数
unordered_map提供了快速的查找速度,其查找操作的平均时间复杂度为常数级别(O(1)),但不保证元素的顺序。
在某些情况下,unordered_map比map更适合,尤其是对于大量数据而言。
unordered_set
unordered_set(无序集合)是C++中的一种关联容器,它存储唯一的元素,且不按照任何顺序组织它们。它的基本操作包括:
- 创建unordered_set:
#include <unordered_set>
std::unordered_set<int> mySet;
// 创建一个空的无序集合,存储整数类型元素
- 向unordered_set中插入元素:
mySet.insert(10);
// 向无序集合中插入元素10 mySet.insert(20);
// 向无序集合中插入元素20
- 检查unordered_set中是否存在某个元素:
if (mySet.find(10) != mySet.end()) { // 元素10存在于无序集合中 }
else { // 元素10不存在于无序集合中 }
- 删除unordered_set中的元素:
mySet.erase(20);
// 删除元素20
- 获取unordered_set中元素的个数:
int size = mySet.size();
// 获取无序集合中元素的个数
unordered_set提供了快速的查找和插入速度,其查找和插入操作的平均时间复杂度为常数级别(O(1))。
由于不会维护元素的顺序,因此在某些情况下,unordered_set比set更适合。
multiset
multiset(多重集合)是C++中的一种关联容器,它允许存储重复的元素,并按照一定的排序规则组织它们。它的基本操作与set类似,但允许存储相同的元素。基本操作包括:
- 创建multiset:
#include <set>
std::multiset<int> myMultiset;
// 创建一个空的多重集合,存储整数类型元素,默认按照升序排序
- 向multiset中插入元素:
myMultiset.insert(10);
// 向多重集合中插入元素10 myMultiset.insert(20);
// 向多重集合中插入元素20 myMultiset.insert(20);
// 向多重集合中再次插入元素20,允许重复插入
- 从multiset中访问元素:
// 可以通过迭代器遍历multiset中的元素
for (auto it = myMultiset.begin(); it != myMultiset.end(); ++it) { std::cout << *it << " ";
}
- 检查multiset中是否存在某个元素:
if (myMultiset.find(10) != myMultiset.end()) { // 元素10存在于多重集合中 }
else { // 元素10不存在于多重集合中 }
- 删除multiset中的元素:
myMultiset.erase(20);
// 删除元素20,只删除一个匹配项
- 获取multiset中元素的个数:
int size = myMultiset.size();
// 获取多重集合中元素的个数,包括重复的元素
multiset中的元素按照排序规则组织,因此它是有序的容器。
相比于set,multiset允许存储重复的元素,并且可以方便地统计重复元素的个数。
tuple
Tuple(元组)是C++中的一种标准库容器,用于存储固定数量的对象。元组中的对象可以是不同的类型,且元组的大小在编译时确定。基本操作包括:
- 创建tuple:
#include <tuple>
std::tuple<int, double, std::string> myTuple(10, 3.14, "hello");
// 创建一个包含int、double和string类型对象的元组
- 访问tuple中的元素:
int intValue = std::get<0>(myTuple);
// 获取第一个元素(整数) double doubleValue = std::get<1>(myTuple);
// 获取第二个元素(双精度浮点数) std::string stringValue = std::get<2>(myTuple);
// 获取第三个元素(字符串)
- 修改tuple中的元素:
std::get<0>(myTuple) = 20;
// 修改第一个元素的值为20
- 将tuple中的元素解包到变量中:
int a;
double b;
std::string c;
std::tie(a, b, c) = myTuple;
// 将元组中的元素解包到变量a、b、c中
- 比较tuple:
使用std::tuple
进行比较时,会按照元素的顺序逐个比较。
std::tuple<int, int> tuple1(1, 2);
std::tuple<int, int> tuple2(1, 3);
if (tuple1 < tuple2) { // tuple1小于tuple2 }
else { // tuple1大于或等于tuple2 }
Tuple可以在不引入新的数据结构的情况下,方便地将多个值打包为一个单元,并支持解包操作。由于元组中的对象类型不必相同,因此在一些特定场景下使用十分方便。
array
在C++中,std::array 是一个模板类,提供了类似于数组的功能,但是具有更多的特性和安全性。它具有固定大小,并且在创建后大小不能更改。以下是 std::array 的基本操作:
- 创建 array:
#include <array>
std::array<int, 5> myArray;
// 创建一个包含5个整数的数组
- 访问 array 中的元素:
myArray[0] = 10;
// 给数组的第一个元素赋值为 10 int value = myArray[1];
// 获取数组的第二个元素的值
- 获取 array 的大小:
int size = myArray.size();
// 获取数组的大小,这里将返回5
- 遍历 array 中的元素:
for (const auto& element : myArray) { cout << element << endl;
}
- 使用迭代器访问 array 中的元素:
for (auto it = myArray.begin(); it != myArray.end(); ++it) { cout << *it << endl;
}
- 初始化 array:
std::array<int, 3> anotherArray = {1, 2, 3};
// 使用初始化列表初始化数组
- 比较 array:
std::array<int, 3> array1 = {1, 2, 3};
std::array<int, 3> array2 = {1, 2, 3}; if (array1 == array2) { // 两个数组相等 }
else { // 两个数组不相等 }
- 填充 array:
myArray.fill(0);
// 将数组中的所有元素填充为0
std::array 提供了数组的很多功能,并且更加安全和方便,因为它提供了许多与容器一样的操作,比如 size()、begin()、end() 等,同时还支持初始化列表和比较操作。
list
链表(List)是一种线性数据结构,它的基本操作包括:
- 创建链表:
#include <list>
std::list<int> myList;
// 创建一个空的整数链表
- 向链表中添加元素:
myList.push_back(10);
// 在链表尾部添加元素10 myList.push_front(20);
// 在链表头部添加元素20
- 从链表中删除元素:
myList.pop_back();
// 删除链表尾部的元素 myList.pop_front();
// 删除链表头部的元素
- 访问链表中的元素:
int frontElement = myList.front();
// 获取链表头部的元素值 int backElement = myList.back();
// 获取链表尾部的元素值
- 检查链表是否为空:
if (myList.empty()) { // 链表为空 }
else { // 链表不为空 }
- 获取链表中元素的个数:
int size = myList.size();
// 获取链表中元素的个数
- 在链表中进行遍历:
for (const auto& element : myList) { // 对链表中的每个元素执行操作
}
链表是一种非常灵活的数据结构,它允许在任意位置插入和删除元素,因此在某些场景下比数组更为适用。
链表的操作复杂度取决于操作的位置,而不是链表的长度。