【C++ STL之vector超详解】

目录

  • 1.头文件
  • 2.初始化方法
  • 3.元素的访问方式
  • 4.vector的功能函数
  • 5.排序
  • 6.访问
  • 7.与普通数组的优劣比较

介绍

vector为可变长数组(动态数组),用于实现动态数组,它提供了动态大小的数组功能,并提供了一些方便的操作和函数来管理数组中的元素。

1.头文件

#include

2.初始化方法

(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));

3.元素的访问方式

//方式一:单个访问,假设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 << " ";

4.vector的功能函数

代码 含义
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;
}

5.排序

使用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;
}

6.访问

(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;
}

7.与普通数组的优劣比较

优势:

动态大小: std::vector 可以动态调整大小,不需要在创建时指定固定大小。这使得它更加灵活,可以根据需要动态地添加或删除元素。

内存管理: std::vector 在底层进行了内存管理,可以自动处理内存的分配和释放,避免了内存泄漏和越界访问的风险。

自动扩展: 当向 std::vector 中添加元素时,如果超过了当前容量,它会自动重新分配更大的内存空间并将元素复制到新空间中。这使得操作方便,不需要手动处理扩容问题。

标准库算法: std::vector 是标准库的一部分,它提供了许多便于操作和处理元素的函数和算法,例如迭代器、排序、查找等。

劣势:

性能: 相对于普通数组,std::vector 可能会稍微有一些性能开销,因为它需要进行内存分配和释放,并且可能会涉及元素的复制操作。

连续内存存储: 普通数组在内存中是连续存储的,这可能会在一些情况下提供更好的缓存性能。而 std::vector 可能会在堆上分配内存,导致数据不一定连续存储。

内存开销: 由于 std::vector 需要额外的内存来管理动态大小和元数据,因此在一些内存受限的环境中,可能会产生一些额外的内存开销。

总之,如果你需要动态大小的容器,并且希望有更高级的内存管理和算法支持,那么 std::vector 是一个不错的选择。但如果你需要最大限度地优化性能或者需要保证连续内存存储,那么普通数组可能更适合。在实际使用中,可以根据具体需求来选择合适的数据结构。

你可能感兴趣的:(c++,开发语言)