STL-vector向量

STL-vector向量

vector数组是一个能 存放任意数据类型(类,结构,普通变量类型等)的动态数组

在数据结构中就相当于顺序储存的线性表,寻找元素非常快,但是插入元素的时间却很大。

与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效

和普通数组一样可以通过下标索引来进行访问

list是一个双向链表,在同一个为止插入大量的数据时速度很快,但是查找的速度就会慢很多

1.头文件

#include<vector>
using namespace std;

2.构造函数

vector<int> vec;       		// 空的vector,只是一个列表的头,里面没有元素
vector<string> vec;
vector<int> vec1 = {1,3,4,5,6};

vector<int> vec1(4, 100);   // 初始化一个具有4个元素的vector,每个元素的值都是100
vector<int> vec2 (vec.begin(), vec.end()); // 通过其他vector的迭代器的方式,进行拷贝复制初始化
vector<int> vec3 (vec);  	// 直接对其他vector的拷贝复制

//二维初始化
vector<vector<int>> vars(size, vector<int>(size, 0)); // (size,size)的矩阵,元素全部是0

//用vector构建二维数组
vector<vector<int>> matrix;
vector<int>a;
a.push_back(1);
a.push_back(3);
a.push_back(1);
matrix.push_back(a);
//或者用下面的方法
int i,j;
vector<vector<int>> array(5);
for (i = 0; i < array.size(); i++)
    array[i].resize(3);//这里一定要使用resize其相当于每行的元素数并已经初始化过了

3.索引存取元素

索引其元素和索引一般的数组元素相似,使用下标或者 at()

operator[index];//类似数组中的[],返回索引index所指向的数据
at(int index);//用at函数来返回索引index所指向的数据
front();//返回容器中的第一个数据
back();//返回容器中最后一个元素
vector<int> vec1 = {1,3,4,5,6};
vec1[1]; 		 		 
// 直接索引,针对多维度的也是一样
输出是3
vec1[1] = 0;			 
//直接可以修改
输出是0
vec1.at(1) = 1;  		 
// 也可以通过函数索引
输出是1
vec1.back(); 			 
// 获取vector的最后一个元素
输出是6


# 输出最小值及索引
*max_element(vec.begin(),vec.end());
*min_element(vec.begin(),vec.end());

# 输出最大最小值索引
max_element(vec.begin(),vec.end())-vec.begin();
min_element(vec.begin(),vec.end())-vec.begin();


4.遍历元素

方法一、索引遍历
vector<int> vars;
int vsize = vars.size();
for (int i = 0; i < vsize; ++i){
	cout << vars[i];
}
方法二、迭代器变量
vector<int> vars = {1,3,5,6,7,8};
for (vector<int>::iterator it = vars.begin(); it != vars.end(); it++){
    cout<< *it  <<""; // 遍历每一个元素
}
指定区间中的遍历;
vector<int> vars = {1,3,5,6,7,8};
for (vector<int>::iterator it = vars.begin()+1; it != vars.end()-1; ++it){
	*it = 10; // 遍历每一个元素
}
方法三、使用auto关键字
for (auto it = vars.begin(); it != vars.end(); ++it){
        cout << " "<< *it; // 遍历每一个元素
    }
//多维度
for (int i = 0; i < vec.size(); i++)
{
    for (int j = 0; j < vec[0].size(); j++)
        cout << vec[i][j] << " ";
    cout << endl;
}


#include <vector>
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> vars = {1, 3, 5, 6, 7, 8};

    vector<vector<int>> vec = {{1, 2, 3}, {4, 5, 6}};

    for (auto iter = vec.begin(); iter != vec.end(); iter++)
    {
        vector<int> vec_tmp = *iter;
        for (auto it = vec_tmp.begin(); it != vec_tmp.end(); it++)
        {
            cout << *it << " ";
        }

        cout << endl;
    }
    return 0;
}

4.capacity 相关

1、vec.size();    
//元素个数

2、vec.max_size();  
//vector 可允许的最大容量

3、vec.resize();  
// 改变容器可以容纳元素的个数,

4、vec.capacoty();    
//理论容量

5、vec.empty(); 
//返回是否为空,true, false;

6、vec.reserve();
// 使得capacity至少能容纳n个元素。

7、vec.shrink_to_fit();
//减小capacity,使其与容器大小相同

5.插入元素

vec.push_back(同类型量);作用是在vector的末尾插入新元素

insert()第一个参数为迭代器,作用为在迭代器前面插入新元素

insert()第一个参数为迭代器,作用为在迭代器前面插入新元素

尾插法

vector<int> vars ;
vars.push_back(10);

insert插入法

vector<int> vars = {1,2,3,4,5};
vars.insert(vars.begin(), 100);
// 插入单个元素,在vars的第0元素位置插入100,位置用迭代器表示
vars.insert(vars.begin(), 2, 100);
// 插入多个相同的元素,此处插入2个100

vector<int> cop = {6,7,8};
vars.insert(vars.end(), cop.begin(), cop.end()); 
// 也可以进行vector之间的拼接

6.删除元素

pop_back()删除最后一个元素。

erase() 删除指定位置元素.(其中的参数要是指针变量,比如begain(),end(),以及迭代器值) 例如vec.erase(vec.begin()+2);删除第3个元素

clear() 清除所有元素。

empty() )判断该数组是否为空

vector<int> vars = {1,2,3,4,5,6};
vars.pop_back(); 
// 弹出最后一个元素,注意只是弹出,不返回其值,用vector.back()返回其值
vars.clear(); // 清空vector
auto iter = vars.erase(vars.begin()+1); 
// 删除单个元素,指定迭代器,删除后vector的大小减1,但是容量不变。
// 其返回一个迭代器,指向被删除元素后的第一个元素。

删除从一个位置到另一个位置
auto iter = vars.erase(vars.begin(), vars.begin()+2); // 删除一个范围内的值,指定开头,结尾的迭代器即可。

7.排序和翻转

#include<algorithm>
//采用的是从小到大的排序 
sort(vec.begin(),vec.end());

// 将元素翻转,即逆序排列
reverse(vec.begin(),vec.end());

8.底层原理

底层原理:动态数组

动态增长的数组,里面有一个指针指向一片连续的内存空间,当空间装不下要容纳的数据的时候会自动申请一片更大的空间(空间配置器)将原来的数据拷贝到新的空间,然后就会释放旧的空间。当释放或者删除(vec.clear())的数据时候并不会释放只是清空了里面的数据。

vector中有三个迭代器first,last,end, 分别指向了数组的开头, 数组的结尾+1以及数组的最大容量结尾,迭代器这里可以理解为是指针

int first,last,end;		
unsigned int size(){		
    //通过首尾 很容易得出size
	return last-first;
}
bool empty(){	
    //可以直接判断是否为空
	return last==first;
}
unsigned int capacity(){	
    //得到当前数组的容量
	return end-begin;
}

vector 容器扩容:

  • 完全弃用现有的内存空间,重新申请更大的内存空间;
  • 将旧内存空间中的数据,按原有顺序移动到新的内存空间中;
  • 最后将旧的内存空间释放。

扩容的倍数关系:在VS中, 该倍数为1.5 而在GCC中, 该倍数为2

reserve是直接扩充到已经确定的大小,可以减少多次开辟、释放空间的问题

resize()可以改变有效空间的大小,也有改变默认值的功能。capacity的大小也会随着改变。resize()可以有多个参数。

9.特殊记忆

互换容器

v1.swap(v2);//将v2的元素与v1元素互换
# 针对二维vector的处理
/ 第一维度从小到大, (第一维度相同时,按第二维度从大到下)

sort(envelopes.begin(),envelopes.end(),[](const auto&a,const auto&b){
	if(a[0]!=b[0]){
		return a[0]<b[0];
	}else{return a[1]>b[1];}
});

函数总结

函数成员 函数功能
成员函数 operator[ ] 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
成员函数 assign() 用新元素替换原有内容。
容量 size() 返回实际元素个数。
容量 max_size() 返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
容量 empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
容量 capacity() 返回当前容量。
元素访问 at() 使用经过边界检查的索引访问元素。
元素访问 front() 返回第一个元素的引用。
元素访问 back() 返回最后一个元素的引用。
元素访问 data() 返回指向容器中第一个元素的指针。
修改器 resize() 改变实际元素的个数。
修改器 reserve() 增加容器的容量。
修改器 push_back() 在序列的尾部添加一个元素。
修改器 pop_back() 移出序列尾部的元素。
修改器 insert() 在指定的位置插入一个或多个元素。
修改器 erase() 移出一个元素或一段元素。
修改器 clear() 移出所有的元素,容器大小变为 0。
修改器 swap() 交换两个容器的所有元素。
迭代器 begin() 返回指向容器中第一个元素的迭代器。
迭代器 end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
迭代器 rbegin() 返回指向最后一个元素的迭代器。
迭代器 rend() 返回指向第一个元素所在位置前一个位置的迭代器。
迭代器 cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
迭代器 cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
迭代器 crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
迭代器 crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
emplace() 在指定的位置直接生成一个元素。
emplace_back() 在序列尾部生成一个元素。

参考资料

C++STL【容器】详解

https://www.w3schools.cn/cpp_standard_library/vector.html

https://www.apiref.com/cpp-zh/cpp/container/vector.html

http://c.biancheng.net/view/6749.html

https://www.cnblogs.com/LyShark/p/17633037.html

posted @ 2024-01-22 19:58  贝壳里的星海  阅读(5)  评论(0编辑  收藏  举报