当前位置: 首页 > article >正文

【C/C++】C++ Vector容器核心操作指南:增删改查全面解析

🔗 运行环境:C/C++

🚩 撰写作者:左手の明天

🥇 精选专栏:《python》

🔥  推荐专栏:《算法研究》

🔐#### 防伪水印——左手の明天 ####🔐

💗 大家好🤗🤗🤗,我是左手の明天!好久不见💗

💗今天分享【C/C++】——vector的增删改查操作💗

📆  最近更新:2025 年 02 月 15 日,左手の明天的第 350 篇原创博客

📚 更新于专栏:C/C++入门与进阶

🔐#### 防伪水印——左手の明天 ####🔐


一、Vector容器概述

Vector是C++标准模板库(STL)中最常用的序列式容器,本质上是一个动态数组。与静态数组相比,vector具有以下核心优势:

  1. 动态扩容:自动管理内存空间,容量随元素增加自动扩展

  2. 类型安全:强类型约束保证数据一致性

  3. 丰富接口:提供超过30种成员函数方便操作

  4. 迭代器支持:兼容STL算法和泛型编程

二、基础操作快速入门

1. 包含头文件

首先,确保你的代码中包含了vector的头文件:

#include <vector>

2. 容器创建与初始化

// 创建空vector
vector<int> v1;

// 指定初始容量
vector<string> v2(10); 

// 初始化列表(C++11)
vector<char> vowels {'a', 'e', 'i', 'o', 'u'};

// 拷贝构造
vector<float> v3(v2);

还可以使用不同的方式来初始化vector

std::vector<int> vec1; // 默认初始化,创建一个空的vector

std::vector<int> vec2(10); // 创建一个包含10个默认值(0)的vector

std::vector<int> vec3(10, 1); // 创建一个包含10个值1的vector

std::vector<int> vec4 = {1, 2, 3, 4, 5}; // 使用初始化列表初始化vector

3. 元素访问操作

vector<double> prices {19.99, 9.99, 15.49};

// 下标访问(不检查越界)
cout << prices[0];  // 19.99

// at()方法(边界检查)
cout << prices.at(1); // 9.99

// 首尾元素访问
cout << prices.front(); // 19.99
cout << prices.back();  // 15.49

三、核心操作深度解析

1. 元素添加操作

vector<int> nums;

// 尾部追加
nums.push_back(10);  // [10]

// 批量插入
nums.insert(nums.end(), {20, 30}); // [10,20,30]

// 指定位置插入
auto it = nums.begin() + 1;
nums.insert(it, 15); // [10,15,20,30]

// 高效构造(C++11)
nums.emplace_back(40); // 避免临时对象拷贝

2. 元素删除操作

  • 删除末尾元素:使用pop_back()方法。

  • 删除指定位置的元素:可以使用erase()方法。

vec1.pop_back(); // 删除vec1的最后一个元素

vec1.erase(vec1.begin() + 2); // 删除vec1中索引为2的元素(注意索引从0开始)

vector<string> names {"Alice", "Bob", "Charlie"};

// 移除末尾元素
names.pop_back();  // 移除"Charlie"

// 删除指定位置
names.erase(names.begin()); // 删除"Alice"

// 范围删除
names.erase(names.begin()+1, names.end()); 

// 清空容器
names.clear();

3. 数据修改操作

直接通过索引访问并修改元素:

vec1[2] = 20; // 将vec1中索引为2的元素修改为20

vector<int> data {1,2,3,4};

// 直接修改元素
data[1] = 20;  // [1,20,3,4]

// 使用迭代器修改
auto it = data.begin() + 2;
*it = 30;      // [1,20,30,4]

// 范围替换
vector<int> newData {5,6,7};
data.swap(newData); // data现在为[5,6,7]

4. 数据查询操作

(1)通过索引访问元素:

int value = vec1[2]; // 获取vec1中索引为2的元素的值

(2)使用find()方法,注意find()返回的是一个迭代器:

vector<string> colors {"red", "green", "blue"};

// 遍历查询
for(const auto& color : colors) {
    if(color == "green") {
        cout << "Found green";
    }
}

// 使用find算法
auto pos = find(colors.begin(), colors.end(), "blue");
if(pos != colors.end()) {
    cout << "Index: " << pos - colors.begin();
}

5. 获取大小和容量

  • 大小:已存储的元素数量。

  • 容量:在不重新分配内存的情况下,容器能保存的元素的最大数量。

std::cout << "Size: " << vec1.size() << std::endl; // 输出vec1的大小(已存储的元素数量)

std::cout << "Capacity: " << vec1.capacity() << std::endl; // 输出vec1的容量(最大存储能力)

四、性能优化与最佳实践

1. 容量管理

vector<int> vec;
vec.reserve(1000);  // 预分配空间,避免多次扩容

2. 高效插入

// 批量插入比单次插入更高效
vector<int> source {1,2,3};
vec.insert(vec.end(), source.begin(), source.end());

3. 删除优化

// 高效移除特定元素(删除所有奇数)
vec.erase(remove_if(vec.begin(), vec.end(), 
                  [](int x){return x%2 !=0;}), 
        vec.end());

五、典型应用场景

  1. 动态数据集处理(实时数据流)

  2. 需要随机访问的集合操作

  3. 替代传统数组的现代化方案

  4. 算法实现中的临时容器

六、注意事项

1. 迭代器失效问题

  • 插入操作可能导致所有迭代器失效

  • 删除操作会使被删元素之后的迭代器失效

2. 复杂度分析

  • 随机访问:O(1)

  • 尾部操作:O(1)

  • 中间插入/删除:O(n)

3. 容器选择建议

  • 频繁头部操作:考虑deque

deque的定义和特性

deque(双端队列)是C++标准模板库(STL)中的一种数据结构,允许在两端进行插入和删除操作。deque是基于动态数组实现的,与vector类似,但deque在两端操作上有更好的性能。其特点包括:

  • 高效的两端操作‌:deque可以在头部和尾部以O(1)的时间复杂度进行插入和删除操作。
  • 非连续存储‌:与vector不同,deque的元素不一定在内存中连续存储,这使得在序列中间插入或删除元素时更加高效‌。

与其他数据结构的比较

  • 与vector的比较‌:虽然deque和vector都使用动态数组实现,但deque允许在两端高效地进行插入和删除操作,而vector只能在尾部高效地进行这些操作。此外,deque的元素不一定连续存储,这使其在序列中间操作时更灵活‌。
  • 与list的比较‌:list是一个双向链表,支持在任意位置的快速插入和删除操作,但其随机访问效率较低。deque在频繁的头部操作上比list更优,但在遍历效率上不如list‌。

使用场景

deque常用于需要频繁在头部和尾部进行操作的场景,如实现栈和队列的底层结构。由于其高效的头部和尾部操作特性,deque在需要快速入栈和出栈的操作中表现优异‌。

  • 大量插入删除:考虑list

七、进阶技巧

  1. 内存分配策略:capacity()和size()的差异

  2. 移动语义优化(C++11)

  3. 自定义分配器使用

  4. 多维vector应用

vector<vector<int>> matrix(5, vector<int>(5)); // 5x5矩阵

总结

Vector作为C++中最核心的容器之一,其灵活性和易用性使其成为开发者的首选容器。通过合理使用增删改查接口,结合性能优化技巧,可以充分发挥vector的优势。建议在实际开发中根据具体需求选择合适的容器,对于需要频繁在中间位置进行插入删除操作的场景,可考虑改用list或deque等其他容器。


http://www.kler.cn/a/548159.html

相关文章:

  • Qt QCommandLinkButton 总结
  • 图的遍历: 广度优先遍历和深度优先遍历
  • no matching cipher found问题一次解决经历
  • 【数据分享】1929-2024年全球站点的逐日降雪深度数据(Shp\Excel\免费获取)
  • python 查询mongo数据批量插入mysql
  • 【devops】Github Actions Secrets | 如何在Github中设置CI的Secret供CI的yaml使用
  • Redis6.2.6下载和安装
  • 硕成C语言22【一些算法和数组的概念】
  • LVS的NAT及DR模式
  • Cookie的学习2.15
  • RadASM环境,win32汇编入门教程之四
  • CAS单点登录(第7版)24.高可用性
  • C语言中的文件
  • C#学习之S参数读取(s2p文件)
  • Selenium自动化测试入门:python unittest 单元测试框架
  • 数字内容体验优化策略:全渠道整合与高效转化实践
  • 草图绘制技巧
  • 【linux】Socket网络编程
  • vue使用v-chart的实践心得
  • 【Elasticsearch】keyword分析器