C++ 学习杂记04:std::vector 类

概述

std::vector是 C++ 标准模板库(STL)中提供的动态数组容器。它能够在运行时动态调整大小,提供随机访问迭代器,是 C++ 中最常用的容器之一。

头文件

复制代码
#include <vector>

类模板声明

复制代码
template<
    class T,
    class Allocator = std::allocator<T>
> class vector;

构造函数

1. 默认构造函数

复制代码
std::vector<T> vec;  // 创建空vector

2. 指定大小构造函数

复制代码
std::vector<T> vec(10);           // 10个默认初始化的元素
std::vector<T> vec(10, value);    // 10个值为value的元素

3. 范围构造函数

复制代码
std::vector<T> vec(other.begin(), other.end());  // 从迭代器范围构造

4. 拷贝构造函数

复制代码
std::vector<T> vec(other);  // 深拷贝

5. 初始化列表构造函数

复制代码
std::vector<T> vec = {1, 2, 3, 4, 5};

常用成员函数

元素访问

复制代码
// 返回指定位置的引用,不进行边界检查
T& operator[](size_type pos);
const T& operator[](size_type pos) const;

// 返回指定位置的引用,进行边界检查(可能抛出std::out_of_range)
T& at(size_type pos);
const T& at(size_type pos) const;

// 返回第一个元素的引用
T& front();
const T& front() const;

// 返回最后一个元素的引用
T& back();
const T& back() const;

// 返回底层数组的指针
T* data() noexcept;
const T* data() const noexcept;

容量相关

复制代码
// 检查是否为空
bool empty() const noexcept;

// 返回元素数量
size_type size() const noexcept;

// 返回最大可能元素数量
size_type max_size() const noexcept;

// 预留容量,减少重新分配次数
void reserve(size_type new_cap);

// 返回当前分配的存储容量
size_type capacity() const noexcept;

// 请求移除未使用的容量
void shrink_to_fit();

修改操作

复制代码
// 清空所有元素
void clear() noexcept;

// 在末尾插入元素
void push_back(const T& value);
void push_back(T&& value);

// 移除末尾元素
void pop_back();

// 在指定位置插入元素
iterator insert(const_iterator pos, const T& value);
iterator insert(const_iterator pos, T&& value);
iterator insert(const_iterator pos, size_type count, const T& value);

// 擦除指定位置的元素
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);

// 调整容器大小
void resize(size_type count);
void resize(size_type count, const T& value);

// 交换两个vector的内容
void swap(vector& other) noexcept;

示例代码

基本使用

复制代码
#include <iostream>
#include <vector>

int main() {
    // 创建vector
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    
    // 添加元素
    numbers.push_back(6);
    
    // 访问元素
    std::cout << "第一个元素: " << numbers.front() << std::endl;
    std::cout << "最后一个元素: " << numbers.back() << std::endl;
    std::cout << "第三个元素: " << numbers[2] << std::endl;
    
    // 遍历vector
    std::cout << "所有元素: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    // 使用迭代器
    std::cout << "使用迭代器: ";
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

容量管理示例

复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;
    
    std::cout << "初始容量: " << vec.capacity() << std::endl;
    
    // 预留空间以提高性能
    vec.reserve(100);
    std::cout << "预留100个元素后的容量: " << vec.capacity() << std::endl;
    
    // 添加元素
    for (int i = 0; i < 50; ++i) {
        vec.push_back(i);
    }
    
    std::cout << "添加50个元素后的大小: " << vec.size() << std::endl;
    std::cout << "添加50个元素后的容量: " << vec.capacity() << std::endl;
    
    return 0;
}

插入和删除示例

复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 5, 6};
    
    // 在位置3插入元素4
    auto it = vec.begin() + 3;
    vec.insert(it, 4);
    
    // 删除元素2
    vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
    
    // 输出结果
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

性能特征

时间复杂度

  • 随机访问:O(1)

  • 在末尾插入/删除:O(1)(平均情况,不考虑重新分配)

  • 在开头或中间插入/删除:O(n)

  • 查找:O(n)(无序情况下)

空间复杂度

  • 连续内存存储

  • 可能需要额外的内存用于管理

使用建议

优点

  1. 随机访问:支持常数时间复杂度的随机访问

  2. 缓存友好:数据连续存储,缓存局部性好

  3. 动态扩容:自动管理内存,无需手动分配

  4. 丰富接口:提供丰富的成员函数和算法支持

注意事项

  1. 中间插入/删除:在vector中间插入或删除元素效率较低

  2. 内存重新分配:扩容时可能导致迭代器失效

  3. 预留空间 :如果知道大致元素数量,使用reserve()提高性能

  4. 大对象:存储大对象时,考虑使用指针或智能指针

迭代器失效规则

  • 插入元素时:如果导致重新分配,所有迭代器、指针、引用失效

  • 插入元素时:如果未重新分配,插入点后的迭代器失效

  • 删除元素时:被删除元素后的迭代器失效

  • reserve():如果增加容量,所有迭代器、指针、引用可能失效

相关算法

复制代码
#include <algorithm>

// 排序
std::sort(vec.begin(), vec.end());

// 查找
auto it = std::find(vec.begin(), vec.end(), value);

// 反转
std::reverse(vec.begin(), vec.end());

// 删除特定元素
vec.erase(std::remove(vec.begin(), vec.end(), value), vec.end());

总结

std::vector是 C++ 中最常用、最通用的容器之一。它结合了数组的随机访问效率和动态数组的灵活性,适用于大多数需要顺序存储数据的场景。正确使用 vector可以提高代码的性能和可维护性。

相关推荐
汉克老师4 小时前
CSP-J 初赛(以满分为目标):第十五课《结构体、排序与自定义比较——从“给数字排队”到“给一群人排队”》
c++·csp-j·小学生·学c++编程
HugoStudio_SWAN5 小时前
C++ CMD 互动动画:按键触发爆炸效果
开发语言·c++·学习·程序人生
水饺编程5 小时前
第5章,[Win32 章节] :Polygon 函数和多边形填充模式
c语言·c++·windows·visual studio
wuminyu5 小时前
Java FFM处理网络读写事件源码剖析
java·linux·c语言·jvm·c++
一木 之林6 小时前
C/C++ 面向对象编程(OOP)(进阶)
java·c语言·c++
千谦阙听7 小时前
C++篇:类和对象(上)
开发语言·c++
_Narcissus_8 小时前
分治&递归
数据结构·c++·笔记·算法·leetcode·递归·分治
牛油果子哥q8 小时前
C++ Socket精讲:TCP/UDP套接字、客户端服务端实现、字节序、粘包拆包、简单HTTP服务、网络踩坑与面试全解
网络·c++·tcp/ip
程与留8 小时前
12_常用控件速查(下):QSpinBox、QSlider、QProgressBar、QCheckBox
c++·qt
OPEN-F9 小时前
C++进阶教程:运算符重载与类型转换
java·c++·算法