介绍
vector为可变长数组(动态数组),用于实现动态数组,它提供了动态大小的数组功能,并提供了一些方便的操作和函数来管理数组中的元素。
#include
(1)一维初始化
vector<变量类型> 变量名
vector<int> num1;//创建一个int类型的num1数组
vector<double> num2;//创建一个double类型的num2数组
vector<ListNode*> num3//创建一个结构体类型储存了链表节点的num3数组
长度和初始值的初始化
vector<int> num1(n);//定义一个长度为n的数组,不指定初值默认初值为0
vector<int> num2(n, 0);//所有的元素均为0
vector<int> num3{1, 2, 3, 4, 5};// 数组num3中有五个元素
(2)数组拷贝
vector<int> num1(n + 1, 0);
vector<int> num2(num1);//两个数组中的类型必须相同,num1和num2都是长度为n+1,所有值都为0的数组
(3)二维数组初始化
vector<int>num1[5];//定义可变长二维数组
//注意:行是不可变的(只有5行),而列可变可以在指定行添加元素
//第一维固定长度为5,第二维长度可以改变
注意:对比上述一维数组的创建()是一维,[ ]是二维。
//行和列均可变
vector<vector<int>>num;//定义一个行和列均可变的二维数组
//行和列是固定的n+1行,m+1列,且初始值都为0.
vector<vector<int> > a(n + 1, vector<int>(m + 1, 0));
//方式一:单个访问,假设num数组中已经有了5个元素
cout << num[1] ; //输出第2个数据
//一二维可变数组和普通数组的访问方法一样
//方式二:遍历
for(int i = 0; i < num.size(); i++)
cout << num[i] << " ";//下标范围在[0,num.size())
//方式三:智能指针
for(auto i : num)
cout << i << " ";
代码 | 含义 |
---|---|
c.front() | 返回第一个数据 |
c.back() | 返回最后一个数据 |
c.pop_back() | 删除最后一个数据 |
c.push_back(element) | 尾插一个数据 |
c.size() | 返回实际数据个数(unsigned类型) |
c.clear() | 不会影响容器的容量大小,只会删除所有元素。 |
c.resize(n,v) | 改变数组大小为n,n个空间数值赋为v,如果没有默认赋值为0 |
c.insert(it,x) | 向任意迭代器it后插入一个元素x(也可插入多个) |
c.erase(first,last) | 删除[first,last)的所有元素 |
c.begin() | 返回首元素的迭代器(地址) |
c.end() | 返回最后一个元素后一个位置的迭代器(地址) |
c.empty() | 判断是否为空,为空返回真,反之返回假 |
下面将以代码形式帮助理解其中一些函数
resize()
#include
int main() {
std::vector<int> myVector = {1, 2, 3, 4, 5};
// 调整容器的大小为 8,新添加的元素将会用 0 初始化
myVector.resize(8);
// 调整容器的大小为 10,新添加的元素将会用 9 初始化
myVector.resize(10, 9);
return 0;
}
insert()
#include
#include
int main() {
std::vector<int> myVector = {1, 2, 4, 5};
// 在索引为 2 的位置插入元素 3
std::vector<int>::iterator it = myVector.begin() + 2;
myVector.insert(it, 3);
// 打印插入后的容器内容:1, 2, 3, 4, 5
for (int num : myVector) {
std::cout << num << " ";
}
return 0;
}
也可插入多个元素
#include
#include
int main() {
std::vector<int> myVector = {1, 5};
// 在索引为 1 的位置插入元素 2, 3, 4
std::vector<int>::iterator it = myVector.begin() + 1;
myVector.insert(it, {2, 3, 4});
// 打印插入后的容器内容:1, 2, 3, 4, 5
for (int num : myVector) {
std::cout << num << " ";
}
return 0;
}
使用sort排序: sort(c.begin(),c.end());
对所有元素进行排序,如果要对指定区间进行排序,可以对sort()里面的参数进行加减改动。
注意:头文件algorithm不要忘
#include
#include
#include // 包含了 sort 函数
int main() {
std::vector<int> myVector = {5, 3, 1, 4, 2};
// 使用 std::sort() 对容器中的元素进行排序
std::sort(myVector.begin(), myVector.end());
// 打印排序后的容器内容
for (int num : myVector) {
std::cout << num << " ";
}
return 0;
}
(1)下标法:
#include
#include
int main() {
std::vector<int> myVector = {1, 2, 3, 4, 5};
// 使用下标法访问数组元素
for (size_t i = 0; i < myVector.size(); ++i) {
std::cout << myVector[i] << " ";
}
return 0;
}
(2)迭代器访问法
#include
#include
int main() {
std::vector<int> myVector = {1, 2, 3, 4, 5};
// 使用迭代器法访问数组元素
for (std::vector<int>::iterator it = myVector.begin(); it != myVector.end(); ++it) {
std::cout << *it << " ";
}
return 0;
}
其中可以把it理解为指向myVector首地址的指针,逐个往后移的过程
(3)智能指针法
智能指针是 C++ 中的一种高级内存管理工具,用于自动管理动态分配的内存,避免内存泄漏和悬挂指针等问题。
#include
#include
#include
int main() {
std::vector<int> myVector = {1, 2, 3, 4, 5};
// 使用 std::shared_ptr 来访问数组元素
for (auto i : myVector) {
std::cout << i << " ";
}
return 0;
}
优势:
动态大小: std::vector 可以动态调整大小,不需要在创建时指定固定大小。这使得它更加灵活,可以根据需要动态地添加或删除元素。
内存管理: std::vector 在底层进行了内存管理,可以自动处理内存的分配和释放,避免了内存泄漏和越界访问的风险。
自动扩展: 当向 std::vector 中添加元素时,如果超过了当前容量,它会自动重新分配更大的内存空间并将元素复制到新空间中。这使得操作方便,不需要手动处理扩容问题。
标准库算法: std::vector 是标准库的一部分,它提供了许多便于操作和处理元素的函数和算法,例如迭代器、排序、查找等。
劣势:
性能: 相对于普通数组,std::vector 可能会稍微有一些性能开销,因为它需要进行内存分配和释放,并且可能会涉及元素的复制操作。
连续内存存储: 普通数组在内存中是连续存储的,这可能会在一些情况下提供更好的缓存性能。而 std::vector 可能会在堆上分配内存,导致数据不一定连续存储。
内存开销: 由于 std::vector 需要额外的内存来管理动态大小和元数据,因此在一些内存受限的环境中,可能会产生一些额外的内存开销。
总之,如果你需要动态大小的容器,并且希望有更高级的内存管理和算法支持,那么 std::vector 是一个不错的选择。但如果你需要最大限度地优化性能或者需要保证连续内存存储,那么普通数组可能更适合。在实际使用中,可以根据具体需求来选择合适的数据结构。