c++ vector介绍

1、什么是vector

std::vector 是C++标准库(STL)中的一个动态数组类模板。它允许存储相同类型的元素集合,并且可以根据需要动态地增加或减少其大小。std::vector 提供了一组函数来访问、插入和删除元素,以及执行其他与数组操作相关的任务。使用 std::vector 可以避免手动管理动态数组时可能遇到的许多常见问题,如内存泄漏和越界访问。

2、vector背后实现原理

std::vector 通常在内部使用一个连续的内存块来存储元素。这意味着它的元素在内存中是顺序排列的,这有助于快速访问和迭代。当 std::vector 需要增长时,它会分配一个更大的内存块,通常大小是原容量的两倍或更多,然后将旧元素复制到新内存块中,并释放旧内存块。这种增长策略有助于减少内存分配和复制操作的次数,但也可能导致一些额外的内存浪费。

3、vector都有哪些操作API,并举例介绍api的使用方法

std::vector 提供了丰富的API来操作元素,以下是一些常用的API及其使用方法:

(1)构造函数
std::vector<int> vec;                       // 默认构造函数,创建一个空的vector  
std::vector<int> vec(10);                  // 创建一个包含10个元素的vector,默认初始化为0  
std::vector<int> vec(10, 5);               // 创建一个包含10个元素的vector,每个元素初始化为5  
std::vector<int> vec2(vec);               // 通过另一个vector复制构造

(2)添加和插入元素
vec.push_back(42);                         // 在vector末尾添加一个元素  
vec.insert(vec.begin(), 100);             // 在vector开始位置插入一个元素  
vec.emplace_back(1, 2, 3);               // 在vector末尾构造并添加一个元素(使用构造函数参数)
(3)访问元素
int first = vec[0];                       // 通过下标访问元素  
int last = vec.back();                    // 访问vector的最后一个元素  
int atThird = vec.at(2);                  // 通过at函数访问元素(会进行范围检查)
(4)删除元素
vec.pop_back();                           // 删除vector的最后一个元素  
vec.erase(vec.begin());                   // 删除vector的第一个元素  
vec.erase(vec.begin() + 1, vec.end() - 1); // 删除一个范围内的元素  
vec.clear();                             // 清空vector,删除所有元素
(5)修改元素大小
vec.resize(20);                           // 改变vector的大小为20,如果新大小大于当前大小,则新元素默认初始化为0  
vec.resize(10, 100);                     // 改变vector的大小为10,如果新大小小于当前大小,则删除多余元素;如果新大小大于当前大小,则新元素初始化为100
(6)容量和大小
size_t size = vec.size();                // 获取vector中元素的个数  
size_t capacity = vec.capacity();       // 获取vector的容量(已分配的内存大小)  
vec.shrink_to_fit();                    // 尝试减少vector的容量以匹配其大小

(7)迭代器
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {  
    std::cout << *it << " ";  
}  
std::cout << std::endl;  
  
// 使用范围for循环  
for (const auto& elem : vec) {  
    std::cout << elem << " ";  
}  
std::cout << std::endl;

4、时间复杂度和空间复杂度

(1)空间复杂度

        std::vector 的空间复杂度是 O(n),其中 n 是当前存储在 vector 中的元素数量。这是因为 vector 需要为其所有元素分配连续的内存空间。此外,vector 还可能分配额外的内存空间以支持未来的增长,但这部分空间仍然与元素数量成线性关系。

(2)时间复杂度

   std::vector 的时间复杂度取决于你执行的具体操作:

  • 访问元素:通过下标访问元素(如 vec[i])是常数时间复杂度 O(1),因为元素在内存中是连续存储的,可以直接通过计算偏移量来访问。

  • 在末尾添加或删除元素:对于 push_backpop_back 等在 vector末尾进行的操作,如果不需要重新分配内存,那么它们是常数时间复杂度 O(1)。然而,如果当前容量不足以容纳新元素,vector 会重新分配内存并复制现有元素到新位置,这种情况下时间复杂度可能达到 O(n)。但是,重新分配是摊还常数时间的,因为它不会每次都发生,且平均下来每次插入或删除操作的时间复杂度仍然是常数。

  • 在任意位置插入或删除元素:对于 insert 和 erase 等在 vector 中间位置进行的操作,时间复杂度是 O(n),因为可能需要移动插入点或删除点之后的所有元素。

  • 改变 vector 的大小:使用 resize 函数改变 vector 的大小,如果新大小大于当前大小,则可能需要构造新的元素(时间复杂度与新增元素的数量成正比);如果新大小小于当前大小,则需要删除多余的元素(时间复杂度与删除元素的数量成正比)。因此,时间复杂度至少是 O(k),其中 k 是改变的大小量。

需要注意的是,虽然 std::vector 在某些情况下可能需要进行内存重新分配和元素复制,但这些操作的开销通常是摊还的,即它们在平均情况下的时间复杂度仍然是相对较低的。因此,std::vector 仍然是一种高效且常用的动态数组实现。

总的来说,std::vector 的空间复杂度是 O(n),而时间复杂度则取决于你执行的具体操作以及是否需要重新分配内存。在实际应用中,由于 vector 提供了高效的内存管理和访问机制,它通常是一个很好的选择,尤其是在需要频繁访问元素或添加元素到末尾的情况下。

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的vector是一个动态数组,可以根据需要随时调整大小。它是标准库中最常用的容器之一,提供了许多方便的成员函数和操作符重载。 使用vector容器需要包含头文件`<vector>`。 下面是一些vector容器的特点和常用操作: 1. 动态大小:vector可以根据需要动态调整大小,可以在任意位置插入或删除元素。 2. 快速随机访问:vector支持通过索引快速访问元素,时间复杂度为O(1)。 3. 连续存储:vector的元素在内存中是连续存储的,这样可以提高访问效率。 4. 自动内存管理:vector会自动管理内部的动态内存分配和释放,无需手动管理。 5. 范围检查:vector会在访问操作时进行边界检查,确保不越界。 以下是一些常用的vector操作: - `push_back(value)`:在vector末尾添加一个元素。 - `pop_back()`:删除vector末尾的元素。 - `size()`:返回vector中元素的个数。 - `empty()`:判断vector是否为空。 - `clear()`:清空vector中的所有元素。 - `at(index)`:返回指定索引位置的元素,并进行范围检查。 - `front()`:返回第一个元素。 - `back()`:返回最后一个元素。 - `insert(iterator, value)`:在指定位置插入一个元素。 - `erase(iterator)`:删除指定位置的元素。 - `begin()`和`end()`:返回指向vector第一个元素和最后一个元素之后的迭代器,用于循环遍历。 vector容器提供了丰富的功能,并且易于使用,适合在需要动态大小和快速访问的情况下使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值