C++ 容器使用指南

C++ 容器使用指南

一.迭代器

当使用 C++ 中的容器(如 std::vectorstd::liststd::map 等)时,迭代器是一种非常重要的工具

它们提供了一种通用的方式来访问容器中的元素,允许我们对容器进行遍历、访问、修改和删除操作

1.开始和结束迭代器

  • begin():返回指向容器第一个元素的迭代器
  • end():返回指向容器尾部(最后一个元素的下一个位置)的迭代器
#include <iostream>
#include <vector>
int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // 使用迭代器遍历容器
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    return 0;
}

2.解引用迭代器

  • *it:解引用迭代器,获取迭代器指向的元素的值
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();
std::cout << *it << std::endl;  // 输出第一个元素的值

3.向容器中插入和删除元素

  • insert(it, value):在迭代器位置插入元素
  • erase(it):删除迭代器指向的元素
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin() + 2;  // 迭代器指向第三个元素
// 在迭代器位置插入元素
vec.insert(it, 10);
// 删除迭代器指向的元素
vec.erase(it);

4. 自增和自减操作

  • ++it:迭代器自增,指向下一个元素
  • --it:迭代器自减,指向前一个元素

5. 检查迭代器是否有效

  • it != container.end():迭代器不等于容器的结束迭代器,表示迭代器有效
  • it == container.end():迭代器等于容器的结束迭代器,表示迭代器无效(已经遍历到容器末尾)

三.动态数组(Vector)(向量)

  • 特点
    • 动态数组,支持随机访问
    • 连续内存存储,支持快速的随机访问和插入删除末尾元素
    • 自动扩展容量,但当容量不够时需要重新分配内存,可能导致性能开销。
  • 注意事项
    • 插入和删除操作在末尾较高效,在中间或头部可能效率较低
    • 当需要频繁在中间位置插入或删除元素时,考虑使用其他容器,如双向链表

1.头文件:

#include <vector>

2.创建和初始化向量

使用 vector 来定义一个向量,可以指定元素类型,也可以不指定类型,默认构造一个空向量

vector<int> myVector;  // 定义一个整数类型的向量,默认为空
vector<int> myVector2(5);  // 定义一个包含5个元素的整数向量,初始值为0
vector<int> myVector3 = {1, 2, 3, 4, 5};  // 初始化一个包含元素的向量

3.添加元素到向量末尾

使用 push_back 函数将元素添加到向量的末尾

myVector.push_back(10);
myVector.push_back(20);
myVector.push_back(30);
// myVector: [10, 20, 30]

4.访问和修改元素

可以使用下标操作符 [] 来访问向量中的元素,也可以使用 at() 函数来访问指定位置的元素。使用这些方式也可以修改元素的值

int firstElement = myVector[0];  // 访问第一个元素
int secondElement = myVector.at(1);  // 访问第二个元素
myVector[2] = 35;  // 修改第三个元素的值为 35

5.获取向量大小

使用 size() 函数来获取向量中元素的数量

cout << "Size of myVector: " << myVector.size() << endl;  // 输出 3

6.迭代访问

可以使用迭代器来遍历向量中的元素

for (auto it = myVector.begin(); it != myVector.end(); ++it) {
    cout << *it << " ";
}
cout << endl;

也可以使用范围-based for 循环来遍历

for (int num : myVector) {
    cout << num << " ";
}
cout << endl;

7.删除元素

  • 使用 pop_back() 函数删除向量末尾的元素
myVector.pop_back();  // 删除末尾的元素
// myVector: [10, 20]
  • 使用 erase() 函数删除指定位置的元素
myVector.erase(myVector.begin() + 1);  // 删除第二个元素
// myVector: [10]

8.清空向量

使用 clear() 函数清空向量中的所有元素

Vector.clear();  // 清空向量
// myVector: []

三.哈希表(映射)(Map)

  • 特点
    • 存储键值对的容器
    • 键是唯一的,值可以重复。
    • 通过键快速查找对应的值
  • 注意事项
    • 插入相同键的元素会覆盖原来的值
    • 查找元素的时间复杂度为 O(log n),插入和删除操作的时间复杂度也为 O(log n)

1.包文件

#include <unordered_map>

1.创建和初始化

#include <iostream>
unordered_map<std::string, int> myMap = {
    {"apple", 5},
    {"banana", 3},
    {"cherry", 7}
};

2.插入和访问元素

  • insert({key, value}):插入键值对
  • operator[]:访问或设置元素值
myMap.insert({"date", 10});  // 插入键值对
myMap["grape"] = 4;          // 设置元素值

// 访问元素
cout << "键值: " << myMap["cherry"] << endl;

3.删除元素

  • erase(key):删除指定键对应的元素
myMap.erase("banana");  // 删除元素

4.检查键是否存在

  • count(key):检查指定键是否存在,返回 1 表示存在,0 表示不存在
if (myMap.count("banana")) {
    cout << "myMap有Banana" << endl;
} else {
    cout << "myMap没有Banana" << endl;
}

5.遍历

可以使用迭代器遍历哈希表中的键值对

for (const auto& pair : myMap) {
    cout << pair.first << " : " << pair.second << endl;
}

6.获取哈希表大小

  • size():返回哈希表中键值对的数量
cout << "Size of myMap: " << myMap.size() << endl;

7.清空哈希表

  • clear():清空哈希表中的所有元素
myMap.clear();  // 清空哈希表

四.双向链表(List)

  • 特点
    • 每个节点有指向前一个和后一个节点的指针
    • 适合频繁在中间位置插入或删除元素
    • 不支持随机访问,需要通过迭代器遍历
  • 注意事项
    • 插入和删除操作效率高,时间复杂度为 O(1)
    • 如果需要随机访问元素,考虑使用其他容器,如向量或集合

1.包文件

#include <list>

2.创建和初始化

// 创建一个整型列表
list<int> myList = {1, 2, 3, 4, 5};

3.插入元素

  • push_back(value):在列表末尾插入元素
  • push_front(value):在列表头部插入元素
  • insert(iterator, value):在指定位置插入元素
myList.push_back(6);          // {1, 2, 3, 4, 5, 6}
myList.push_front(0);         // {0, 1, 2, 3, 4, 5, 6}
auto it = myList.begin();     // 获取迭代器指向头部
myList.insert(++it, 10);      // {0, 10, 1, 2, 3, 4, 5, 6}

4.删除元素

  • pop_back():删除列表末尾元素
  • pop_front():删除列表头部元素
  • erase(iterator):删除指定位置的元素
  • remove(value):删除所有等于指定值的元素
codemyList.pop_back();            // {0, 10, 1, 2, 3, 4, 5}
myList.pop_front();               // {10, 1, 2, 3, 4, 5}
auto it2 = myList.begin();
myList.erase(++it2);              // {10, 2, 3, 4, 5}
myList.remove(3);                 // {10, 2, 4, 5}

5.访问元素

  • 使用迭代器遍历列表元素
  • begin() 返回指向列表第一个元素的迭代器
  • end() 返回指向列表末尾(最后一个元素的下一个位置)的迭代器
// 遍历列表
for (auto it = myList.begin(); it != myList.end(); ++it) {
    cout << *it << " ";
}
cout << endl;

// 反向遍历列表
for (auto rit = myList.rbegin(); rit != myList.rend(); ++rit) {
    std::cout << *rit << " ";
}
cout << endl;

6.获取列表大小

cout << "列表的大小: " << myList.size() << endl;
  • size():返回列表中元素的数量

7.清空列表

myList.clear();                // {}
  • clear():清空列表中所有元素

五.集合 (Set)

  • 特点
    • 存储一组不重复元素的容器
    • 自动排序(有序集合)或无序(无序集合)
    • 支持快速查找、插入和删除操作
  • 注意事项
    • 插入相同键的元素会覆盖原来的值
    • 查找元素的时间复杂度为 O(log n),插入和删除操作的时间复杂度也为 O(log n)

1.包文件

#include <set>

2.创建和初始化

// 创建一个整型集合
set<int> mySet = {4, 2, 1, 3, 5};

3.插入元素

  • insert(value):插入一个元素到集合中。
mySet.insert(6); // {1, 2, 3, 4, 5, 6}

4.删除元素

  • erase(value):删除指定值的元素。
  • erase(iterator):通过迭代器删除元素。
mySet.erase(3);  // {1, 2, 4, 5, 6}

5.查找元素

  • find(value):查找指定值的元素,返回指向该元素的迭代器。如果不存在,返回 end()
auto it = mySet.find(4);
if (it != mySet.end()) {
    cout << "查询:" << *it << endl;
} else {
    cout << "未查询到" << endl;
}

6.遍历集合

for (auto it = mySet.begin(); it != mySet.end(); ++it) {
    std::cout << *it << " ";
}
cout << endl;

7.获取集合大小

  • size():返回集合中元素的数量。
cout << "集合的大小: " << mySet.size() <<endl;

8.清空集合

  • clear():清空集合中所有元素。
mySet.clear();

六.堆栈 (Stack)

  • 特点
    • 后进先出(LIFO)的数据结构。
    • 只能在顶部添加和删除元素。
    • 用于函数调用、表达式求值等场景。
  • 注意事项
    • 使用 top() 前需确保堆栈非空,否则可能会导致未定义行为。
    • 操作堆栈的时间复杂度为 O(1)。

1.包文件

#include <stack>

2.创建和初始化

stack<int> myStack;

3.基本操作

  • push(value):将元素压入堆栈的顶部
  • pop():从堆栈顶部移除元素
  • top():获取堆栈顶部的元素
myStack.push(1);
myStack.push(2);
myStack.push(3);

// myStack: [1, 2, 3]

int topElement = myStack.top();  // 获取顶部元素,topElement = 3

myStack.pop();  // 移除顶部元素

// myStack: [1, 2]

4.检查堆栈是否为空

  • empty():如果堆栈为空,返回 true,否则返回 false
if (myStack.empty()) {
    cout << "堆栈为空." << endl;
} else {
    cout << "堆栈不为空" << endl;
}

5.获取堆栈大小

  • size():返回堆栈中元素的数量。
cout << "堆栈的大小: " << myStack.size() << endl;

七. 队列 (Queue)

  • 特点
    • 先进先出(FIFO)的数据结构
    • 只能在队尾添加元素,在队首移除元素
    • 用于任务调度、广度优先搜索等场景
  • 注意事项
    • 当队列为空时,尝试访问头部元素或移除元素会导致未定义行为
    • 操作队列的时间复杂度为 O(1)

1.包文件

#include <queue>

2.创建和初始化

queue<int> myQueue;

3.基本操作

  • push(value):将元素压入队列的末尾
  • pop():从队列的头部移除元素
  • front():获取队列头部的元素值
  • back():获取队列末尾的元素值
myQueue.push(1);
myQueue.push(2);
myQueue.push(3);

// myQueue: [1, 2, 3]

int frontElement = myQueue.front();  // 获取头部元素,frontElement = 1
int backElement = myQueue.back();    // 获取末尾元素,backElement = 3

myQueue.pop();  // 移除头部元素

// myQueue: [2, 3]

4.检查队列是否为空

  • empty():如果队列为空,返回 true,否则返回 false
if (myQueue.empty()) {
    cout << "队列为空" << endl;
} else {
    cout << "队列不为空" << endl;
}

5.获取队列大小

  • size():返回队列中元素的数量。
cout << "队列大小:" << myQueue.size() << endl;

后记

感谢读者阅读并关注博客文章,并对文章中提到的观点、建议或批评表示感谢✨✨✨

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明月落乌江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值