首页 > 编程语言 >深入解析C++标准库中的std::vector容器

深入解析C++标准库中的std::vector容器

时间:2024-07-01 20:59:36浏览次数:3  
标签:std 元素 C++ 插入 vector 内存 vec

1. 底层实现

std::vector 是C++标准库中的一个模版类,用于动态数组。它的底层实现可以理解为一个动态分配的连续内存块,当需要更多空间时,内存会自动扩展。

  • 内存分配vector 使用一块连续的内存存储元素。当插入新元素导致容量不足时,vector 会分配一块更大的内存(通常是当前容量的两倍),然后将现有元素复制过去,并释放旧的内存。
  • 动态调整:为了高效增加容量,vector 使用一个称为“几何增长”的策略,即每次扩容会增加当前容量的倍数,而非线性增加。这使得插入操作的摊销时间复杂度为 O(1)。

2. 缺点和比较

在讨论vector的缺点时,可以和其他类似的容器(如std::dequestd::list)对比:

  • std::vector
    • 缺点
      • 内存需要连续,因此在大容量时,可能难以找到足够的一块连续内存,导致内存分配失败。
      • 插入和删除操作在非尾部位置有较高的开销,需要移动所有后续元素,时间复杂度为 O(n)。
    • 对比std::deque 允许在两端快速插入/删除,没有连续内存的限制;std::list 是双向链表,可以在任意位置快速插入/删除,但不支持随机访问。

3. 优点和使用场景

  • 优点

    • 支持随机访问(访问任何元素的时间复杂度为 O(1)),适合需要频繁访问元素的场景。
    • 自动管理内存,支持动态增长,且摊销的插入时间复杂度为 O(1)。
    • 提供了一整套的STL算法支持,使用非常方便。
  • 使用场景

    • 适合需要频繁访问和遍历元素的场景,比如实现一个数组、栈等。
    • 适用于元素插入和删除主要发生在容器末尾的情况,因为在末尾进行操作的复杂度是 O(1)。

4. 补充和代码示例

以下是关于 std::vector 的一些常见操作示例:

#include <iostream>
#include <vector>

int main() {
    // 定义一个 vector 并初始化
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 向 vector 尾部添加元素
    vec.push_back(6);

    // 插入元素
    vec.insert(vec.begin() + 2, 10); // 在第三个位置插入 10

    // 删除元素
    vec.erase(vec.begin() + 1); // 删除第二个位置的元素

    // 访问元素
    for (size_t i = 0; i < vec.size(); ++i) {
        std::cout << "Element at index " << i << ": " << vec[i] << std::endl;
    }

    // 使用迭代器访问元素
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << "Element: " << *it << std::endl;
    }

    // 当前容量和大小
    std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;

    // 缩减内存
    vec.shrink_to_fit();
    std::cout << "Size after shrink: " << vec.size() << ", Capacity after shrink: " << vec.capacity() << std::endl;

    return 0;
}

总结

  • 底层std::vector 是一个动态数组,内存由动态分配的连续内存块管理。
  • 缺点
    • 内存必须连续,可能导致大容量时内存分配失败。
    • 中间插入/删除操作开销较大。
  • 优点
    • 支持随机访问。
    • 动态增长,摊销插入时间复杂度为 O(1)。
  • 使用场景
    • 适合频繁访问和遍历,以及主要在末尾进行插入/删除操作的场景。

标签:std,元素,C++,插入,vector,内存,vec
From: https://blog.csdn.net/m0_72877724/article/details/140068634

相关文章

  • C++仿SKData实现C原生指针管理
    template<typenameT>classHBData{public:HBData(T*other_data,size_tother_size,boolrelease):data(other_data),size(other_size),isDeepCopy(release){}HBData(constHBData&other){if(isDeepCopy&&data)......
  • C/C++ Dijkstra(迪杰斯特拉)算法详解及源码
    Dijkstra(迪杰斯特拉)算法是一种用于寻找带权重图中的最短路径的算法。它由荷兰计算机科学家EdsgerDijkstra于1956年提出,被广泛应用于网络路由算法和地图路线规划等领域。算法思想:初始化一个距离数组,用于保存起点到每个顶点的当前最短距离(初始时将起点距离设置为0,其他顶......
  • 信息学奥赛一本通C++版 1081:分苹果 答案
    目录【链接】【题目描述】【输入】【输出】【输入样例】【输出样例】【答案】【链接】1081:分苹果1081:分苹果【题目描述】把一堆苹果分给n个小朋友,要使每个人都能拿到苹果,而且每个人拿到的苹果数都不同的话,这堆苹果至少应该有多少个?【输入】一个不大于1000的......
  • 奥赛一本通C++版 1057解题思路(附加答案)
    链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1057题目:解题思路:先定义两个整型变量a和b,一个字符变量c,依次输入a,b,c。接着判断输入的运算符号是否等于+ || - || * || /(注意,这里的符号用单引号括起来)。如果运算符号等于加号,则进行加法运算,把a和b相加,......
  • 用C++解决编程题目:角谷猜想
    学习目标:用C++编写简单的题目学习内容:#include<iostream>usingnamespacestd;intmain(){longlongn;cin>>n;while(n!=1){if(n%2==1){cout<<n<<"*3+1="<<n*3+1<<endl;n=3*n+1;......
  • C++实现简化版Qt的QObject(3):增加父子关系、属性系统
    前几天写了文章:C++实现一个简单的Qt信号槽机制C++实现简化版Qt信号槽机制(2):增加内存安全保障之后感觉还不够过瘾,Qt中的QObject体系里还有不少功能特性没有实现。为了提高QObject的还原度,今天我们将父子关系、属性系统等功能也一并实现。接口设计首先,我们设计一下我们的......
  • 超详细的 C++中的封装继承和多态的知识总结<1.封装>
    引言  小伙伴们都知道C++面向对象难,可是大家都知道,这个才是C++和C的真正区别的地方,也是C++深受所有大厂喜爱的原因,它的原理更接近底层,它的逻辑更好,但是学习难度高,大家一定要坚持下来呀,本章呢对于C++有关的知识开始讲解封装继承和多态。好了啦废话不多说,跟着小杨一起开始......
  • 华为OD机试D卷 --智能成绩表--24年OD统一考试(Java & JS & Python & C & C++)
    文章目录题目描述输入描述输出描述用例题目解析算法源码题目描述小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?输入描述第1行输入两个整数,学生人数n和科目数量m。0<n<1000<m<10第2行输入m个科目名称,彼......
  • 华为OD机试D卷 --最富裕的小家庭--24年OD统一考试(Java & JS & Python & C & C++)
    文章目录题目描述输入描述输出描述用例题目解析算法源码题目描述在一颗树中,每个节点代表一个家庭成员,节点的数字表示其个人的财富值,一个节点及其直接相连的子节点被定义为一个小家庭。现给你一颗树,请计算出最富裕的小家庭的财富和。输入描述第一行为一......
  • 华为OD机试D卷 --最多购买宝石数目--24年OD统一考试(Java & JS & Python & C & C++)
    文章目录题目描述输入描述输出描述用例1用例2用例3用例4题目解析算法源码题目描述橱窗里有一排宝石,不同的宝石对应不同的价格,宝石的价格标记为gems[i]0≤i<nn=gems.length宝石可同时出售0个或多个,如果同时出售多个,则要求出售的宝石编号连续;......