STL vector容器
前言
vector 容器是 STL 中最常用的容器之一,它和 array 容器非常类似,都可以看做是对 C++ 普通数组的“升级版”。不同之处在于,array 实现的是静态数组(容量固定的数组),而 vector 实现的是一个动态数组,即可以进行元素的插入和删除,在此过程中,vector 会动态调整所占用的内存空间,整个过程无需人工干预。
vector 常被称为向量容器,因为该容器擅长在尾部插入或删除元素,在常量时间内就可以完成,时间复杂度为O(1);而对于在容器头部或者中部插入或删除元素,则花费时间要长一些(移动元素需要耗费时间),时间复杂度为线性阶O(n)。
定义
向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)可以认为是一个动态数组,其中一个vector中的所有对象都必须是同一种类型的。
基本概念
功能:vector容器的功能和数组非常相似,使用时可以把它看成一个数组
vector和普通数组的区别:
1.数组是静态的,长度不可改变,而vector可以动态扩展,增加长度
2.数组内数据通常存储在栈上,而vector中数据存储在堆上
动态扩展:(这个概念很重要)
动态扩展并不是在原空间之后续接新空间,而是找到比原来更大的内存空间,将原数据拷贝到新空间,释放原空间
注意:使用vector之前必须包含头文件 #include<vector>
创建 vector 容器的几种方式
创建 vector 容器的方式有很多,大致可分为以下几种。
1) 如下代码展示了如何创建存储 double 类型元素的一个 vector 容器:
std::vector<double> values;
如果程序中已经默认指定了 std 命令空间,这里可以省略 std::。
注意,这是一个空的 vector 容器,因为容器中没有元素,所以没有为其分配空间。当添加第一个元素(比如使用 push_back() 函数)时,vector 会自动分配内存。
在创建好空容器的基础上,还可以像下面这样通过调用 reserve() 成员函数来增加容器的容量:
values.reserve(20);
这样就设置了容器的内存分配,即至少可以容纳 20 个元素。注意,如果 vector 的容量在执行此语句之前,已经大于或等于 20 个元素,那么这条语句什么也不做;另外,调用 reserve() 不会影响已存储的元素,也不会生成任何元素,即 values 容器内此时仍然没有任何元素。
还需注意的是,如果调用 reserve() 来增加容器容量,之前创建好的任何迭代器(例如开始迭代器和结束迭代器)都可能会失效,这是因为,为了增加容器的容量,vector<T> 容器的元素可能已经被复制或移到了新的内存地址。所以后续再使用这些迭代器时,最好重新生成一下。
2) 除了创建空 vector 容器外,还可以在创建的同时指定初始值以及元素个数,比如:
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
这样就创建了一个含有 8 个素数的 vector 容器。
3) 在创建 vector 容器时,也可以指定元素个数:
std::vector<double> values(20);
如此,values 容器开始时就有 20 个元素,它们的默认初始值都为 0。
注意,圆括号 () 和大括号 {} 是有区别的,前者(例如 (20) )表示元素的个数,而后者(例如 {20} ) 则表示 vector 容器中只有一个元素 20。
如果不想用 0 作为默认值,也可以指定一个其它值,例如:
std::vector<double> values(20, 1.0);
第二个参数指定了所有元素的初始值,因此这 20 个元素的值都是 1.0。
值得一提的是,圆括号 () 中的 2 个参数,既可以是常量,也可以用变量来表示,例如:
int num=20;
double value =1.0;
std::vector<double> values(num, value);
4) 通过存储元素类型相同的其它 vector 容器,也可以创建新的 vector 容器,例如:
std::vector<char>value1(5, 'c');
std::vector<char>value2(value1);
由此,value2 容器中也具有 5 个字符 'c'。在此基础上,如果不想复制其它容器中所有的元素,可以用一对指针或者迭代器来指定初始值的范围,例如:
int array[]={1,2,3};
std::vector<int>values(array, array+2);//values 将保存{1,2}
std::vector<int>value1{1,2,3,4,5};
std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保存{1,2,3}
由此,value2 容器中就包含了 {1,2,3} 这 3 个元素。
成员函数
| begin() | 返回指向容器中第一个元素的迭代器。
| end() | 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
| rbegin() | 返回指向最后一个元素的迭代器。
| rend() | 返回指向第一个元素所在位置前一个位置的迭代器。
| cbegin() | 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
| cend() | 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
| crbegin() | 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
| crend() | 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
| size() | 返回实际元素个数。
| max_size() | 返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
| resize() | 改变实际元素的个数。
| capacity() | 返回当前容量。
| empty() | 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
| reserve() | 增加容器的容量。
| shrink _to_fit() | 将内存减少到等于当前元素实际所使用的大小。
| operator[ ] | 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
| at() | 使用经过边界检查的索引访问元素。
| front() | 返回第一个元素的引用。
| back() | 返回最后一个元素的引用。
| data() | 返回指向容器中第一个元素的指针。
| assign() | 用新元素替换原有内容。
| push_back() | 在序列的尾部添加一个元素。
| pop_back() | 移出序列尾部的元素。
| insert() | 在指定的位置插入一个或多个元素。
| erase() | 移出一个元素或一段元素。
| clear() | 移出所有的元素,容器大小变为 0。
| swap() | 交换两个容器的所有元素。
| emplace() | 在指定的位置直接生成一个元素。
| emplace_back() | 在序列尾部生成一个元素。
void printVector(vector<int>& v)
{ //利用迭代器打印 v
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
部分详解!!!
2. 构造函数:
2.1 一般情况
vector vecName(); // 构造一个空vector,其中包含的对象为int类型
vector vecName(3); // 构造一个空vector,其中包含的对象为int类型,大小为3
vector vecName(3,value); // 构造一个空vector,其中包含的对象为int类型,大小为3,对象均为value
vector vecName = { 1, 2, 3, 4 }; // 构造一个vector,初始值为[1,2,3,4]
vector vecName(vecName2); // 构造一个vector,初始值为另一个vector类型的vecName2
2.2 将vec1的部分赋给vec2
vector<int>::const_iterator First = vec1.begin() + 1; // 找到开始迭代器
vector<int>::const_iterator Second = vec1.begin() + 4; // 找到结束迭代器
vector<int> vec2(First, Second); // 将值直接初始化到vec2(需要注意包括开头,但不包括结尾,即vec2只包含vec[1]到vec[3]的元素)
2.3 二维数组构造方法
vector<vector > vecName(3); // 构造一个二维vector,其中一个维度为3
vector<vector > vecName(3,vector(4)); // 构造一个3*4 的二维vector,其中默认值为0
vector<vector > vecName(3, vector(4,1)); // 构造一个3*4 的二维vector,值均为1
vector<vector > vecName = { {1, 2, 3}, {4, 5, 6} }; // 构造一个2*3 的二维vector,并赋值
3. 增加元素:
vec1.push_back(x); // 在vec1的尾部添加一个元素x(注意:一般可以用emplace_back()代替,效率更高)
vec1.insert(iterator iter, x); // 在vec1的迭代器iter指向元素前增加一个元素x
vec1.insert(iterator iter, int n, x); // 在vec1的迭代器iter指向元素前增加n个元素x
vec1.insert(iterator iter, const_iterator first,const_iterator last); // 在vec1的迭代器iter指向元素前插入另一个相同类型向量的[first,last)间的数据
4. 删除元素:
vec1.pop_back(); // 删除在vec1的最后一个元素
vec1.clear(); // 删除vec1中所有元素
vec1.erase(iterator iter); // 删除vec1中迭代器指向元素
vec1.erase(iterator first,iterator last); // 删除vec1中[first,last)中元素
5. 使用元素:
5.1 一般使用法
vec1[1]; // 使用下标方式
vec1.at(1); // 使用at方式
vec1.front(); // 使用第一个元素
vec1.back(); // 使用最后一个元素
5.2迭代器指针使用法:
iterator begin(); // 返回向量头指针,指向第一个元素
vector<int>::iterator d = vec1.begin();
int d1 = *d;//vec1[0]
iterator end(); // 返回向量尾指针,指向向量最后一个元素的下一个位置
vector<int>::iterator e = vec1.end() - 1;
int e1 = *e;//vec1[last]`
反向迭代器,是从后往前数的,即+1代表向前数一个元素
reverse_iterator rbegin(); // 反向迭代器,指向最后一个元素
vector<int>::reverse_iterator f = vec1.rbegin();
int f1 = *f;//vec1[last]`
reverse_iterator rend(); // 反向迭代器,指向第一个元素之前的位置,也就是vector[-1]
vector<int>::reverse_iterator g = vec1.rend() - 1;
int g1 = *g;//vec1[0]
6. 判断是否为空:
bool empty() const:判断向量是否为空,若为空,则向量中无元素
vector<int> vec1 = { 1, 2, 3, 4, 5 };
bool i = vec1.empty();//输出:false
vector<int> vec2 = { };
bool j = vec2.empty();//输出:true
7. 大小函数:
unsigned int length = vec1.size()//vec1所含元素的个数
8. 使用时的注意事项:
8.1 头文件及其命名空间
#include<vector>
using namespace std;
8.2 Vector 作为函数的返回值时,
方法一:vector<int> fun1(int num);(不推荐)
方法二:bool fun1(int num, vector<int> $&$vec);(推荐)
8.3 将vec2中的内容追加到vec1的后面:
vec1.insert(vec1.end(), vec2.begin(), vec2.end());
8.4 最大最小元素及其索引:
#include<algorithm>
vector<double>::iterator biggest = max_element(begin(vec1), end(vec1));
double biggestValue = *biggest;//最大值
int biggestIndex = distance(begin(begin(vec1), biggest);//最大值索引
vector<double>::iterator smallest = min_element(begin(vec1), end(vec1));
double smallestValue = *smallest;//最大值
int smallestIndex = distance(begin(begin(vec1), smallest);//最大值索引
代码演绎
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//初始化一个空vector容量
vector<char>value;
//向value容器中的尾部依次添加 S、T、L 字符
value.push_back('S');
value.push_back('T');
value.push_back('L');
//调用 size() 成员函数容器中的元素个数
printf("元素个数为:%d\n", value.size());
//使用迭代器遍历容器
for (auto i = value.begin(); i < value.end(); i++) {
cout << *i << " ";
}
cout << endl;
//向容器开头插入字符
value.insert(value.begin(), 'C');
cout << "首个元素为:" << value.at(0) << endl;
return 0;
}
输出结果:
元素个数为:3
S T L
首个元素为:C
没啥别的了吧。。。。
本文作者:PassName
本文链接:https://www.cnblogs.com/spaceswalker/p/15911241.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步