C++STL之vector容器

本文详细介绍了C++STL中的vector容器,包括其基本概念、构造函数、赋值操作、容量与大小管理、数据存取、元素互换、预留空间、存放内置及自定义数据类型,以及容器嵌套。vector作为动态数组,擅长尾部插入和删除,提供高效的操作方式。文章通过实例展示了如何使用各种成员函数,并对比了vector与普通数组的区别,帮助读者深入理解vector的使用和性能优化。
摘要由CSDN通过智能技术生成

C++STL之vector容器(万字详解)



前言

STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装。

C++ 对模板(Template)支持得很好,STL 就是借助模板把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。例如,vector 的底层为顺序表(数组),list 的底层为双向链表,deque 的底层为循环队列,set 的底层为红黑树,hash_set 的底层为哈希表。


vector 常被称为向量容器,因为该容器擅长在尾部插入或删除元素,在常量时间内就可以完成,时间复杂度为O(1);而对于在容器头部或者中部插入或删除元素,则花费时间要长一些(移动元素需要耗费时间),时间复杂度为线性阶O(n)。

一、vector基本概念

使用vector容器时,需要调用头文件#include < vector >

功能

vector数据结构和数组非常相似、也称为单端数组

vector与普通数组区别:

数组是静态空间、而vector可以动态扩展

动态扩展:并不是在原空间之后续接新空间、而是找更大的内存空间、然后将元数据拷贝到新空间、释放原空间

vetcor容器图解

在这里插入图片描述

二、vector构造函数

功能描述

创建vector容器

函数原型

vector<T> v; //采用模板实现类实现、默认构造函数
vector(v.begin(), v.end());//将v[begin(),end()]区间中的元素拷贝给本身
vector(n, item)//构造函数将n个item拷贝给本身
vector(const vector &vec);//拷贝构造函数
vector<T> v{a1,a2,a3};//创建的同时指定初始值以及元素个数

代码展示

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、vector赋值操作

功能描述

给vector容器赋值

函数原型

vector& operator=(const vector &vec);//重载等号操作符
assign(begin,end);//将[begin,end]区间中的数据拷贝赋值给本身
assign(n,item);//将n个item拷贝赋值给本身

代码展示

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

int main()
{
	vector<int> v1; //无参构造
	for(int i=0;i<10;i++)
	v1.push_back(i);
	for(vector<int>::iterator it = v1.begin();it != v1.end();it++)
	cout<< *it << " ";
	cout<<endl;
	
	vector<int> v2(v1.begin(),v1.end());
	for(vector<int>::iterator it = v2.begin();it != v2.end();it++)
	cout<< *it << " ";
	cout<<endl;
	
	vector<int> v3(10,7);
	for(vector<int>::iterator it = v3.begin();it != v3.end();it++)
	cout<< *it << " ";
	cout<<endl;
	
	vector<int> v4(v3);
	for(vector<int>::iterator it = v4.begin();it != v4.end();it++)
	cout<< *it << " ";
	cout<<endl;
	
	vector<int> v5{1,3,4,5,67,8};
	for(vector<int>::iterator it = v5.begin();it != v5.end();it++)
	cout<< *it << " ";
	cout<<endl;
	
	vector<int> v6;
	v6 = v1;
	for(vector<int>::iterator it = v6.begin();it != v6.end();it++)
	cout<< *it << " ";
	cout<<endl;
	
	vector<int> v7;
	v7.assign(v1.begin(),v1.end());
	for(vector<int>::iterator it = v7.begin();it != v7.end();it++)
	cout<< *it << " ";
	cout<<endl;	
	
	vector<int> v8;
	v8.assign(10,1);
	for(vector<int>::iterator it = v8.begin();it != v8.end();it++)
	cout<< *it << " ";
	cout<<endl;	
	return EXIT_SUCCESS;
} 

从上到下分别为v1至v8的输出结果
在这里插入图片描述

iterator 为C++ STL迭代器,用法详解查看主页博客相关文章

四、vector容量和大小

功能描述

对vector容器的容量和大小操作

函数原型

empty();//判断容器是否为空
capacity();//容器的容量
size();//返回容器中元素的个数
resize(int num);//重新指定容器的长度为num、若容器变长,则以默认值填充新位置。
				//若容器变短,则末尾超出容器长度的元素被删除
resize(int num, item);//重新指定容器的长度为num、若容器变长,则以item填充新位置。
				//若容器变短,则末尾超出容器长度的元素被删除

判断是否为空 — empty
返回元素个数 — size
返回容器容量 — capacity
重新指定大小 — resize

代码展示

	vector<int> v1{1,2,3,4,5,6};
	if(v1.empty())
		cout<<"v1是空的"<<endl;
	else
		cout<<"v1不是空的"<<endl; 	
	cout<<v1.empty()<<endl;
	cout<<"v1 的容量"<<v1.capacity()<<endl;
	cout<<"v1 的元素个数"<<v1.size()<<endl;
	 
	v1.resize(10,1);
	for(vector<int>::iterator it = v1.begin();it != v1.end();it++)
	cout<< *it << " ";
	cout<<"v1 的容量"<<v1.capacity()<<endl;
	cout<<"v1 的元素个数"<<v1.size()<<endl;

在这里插入图片描述

vector自动扩容所以v1的容量从6扩容到了12

五、vector数据存取

功能描述

对vector中的数据的存取操作

函数原型

at(int id);//返回索引id所指的数据
operator[];//返回索引id所指的数据
front();//返回容器中第一个数
back();//返回容器最后一个数据

代码展示

	vector<int> v1{1,2,3,4,5,6};
	
	cout<<v1.at(2)<<endl;
	
	cout<<v1[2]<<endl;
	
	cout<<v1.front()<<endl;
	
	cout<<v1.back()<<endl;

在这里插入图片描述

六、vector互换容器

功能描述

实现两个容器内元素进行互换

函数原型

swap(v);//将v与本身的元素互换

代码展示

	vector<int> v1{1,2,3,4,5,6};
	vector<int> v2{7,77,777,7777};
	
	cout<<"v1的元素"<<endl; 
	for(vector<int>::iterator it = v1.begin();it != v1.end();it++)
	cout<< *it << " ";
	cout<<endl; 
	
	cout<<"v2的元素"<<endl; 
	for(vector<int>::iterator it = v2.begin();it != v2.end();it++)
	cout<< *it << " ";
	cout<<endl; 
	
	v1.swap(v2);
	
	cout<<"v1的元素"<<endl; 
	for(vector<int>::iterator it = v1.begin();it != v1.end();it++)
	cout<< *it << " ";
	cout<<endl; 
	
	cout<<"v2的元素"<<endl; 
	for(vector<int>::iterator it = v2.begin();it != v2.end();it++)
	cout<< *it << " ";
	cout<<endl; 

在这里插入图片描述

七、vector预留空间

功能描述

减少vector在动态扩展容量时的扩展次数

函数原型:

reserve(int length);//容器预留length个元素长度,预留位置不初始化,元素不可访问

代码展示

	vector<int> v1{1,2,3,4,5,6};
	cout<<"v1之前的容量"<<v1.capacity()<<endl;
	v1.reserve(10);
	cout<<"v1现在的容量"<<v1.capacity()<<endl; 

在这里插入图片描述

八、vector存放内置数据类型

容器:vector
算法:for_each
迭代器:vector::iterator

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void Print(int val)
{
	cout<<val<<endl;
}
void Vector()
{
	//创建容器 
	vector<int> v;
	//存放数据
	v.push_back(1); 
	v.push_back(2); 
	v.push_back(3); 
	v.push_back(4); 
	
	//迭代器遍历
	//v.begin() 容器第一个元素 
	//v.end() 容器最后一个元素 
	//vector<int>::iterator 获取vector<int>迭代器的类型 
	vector<int>::iterator v_begin = v.begin();
	vector<int>::iterator v_end = v.end();
	
	//第一种遍历方式
	while(v_begin != v_end)
	{
		cout<< *v_begin <<endl;
		v_begin++;
	} 
	//第二种遍历方式
	for(vector<int>::iterator it = v.begin();it != v.end();it++)
	{
		cout<< *it << " "<< endl;
	} 
	cout<<endl;
	//第三种遍历方式:使用STL提供的标准遍历算法
	 for_each(v.begin(),v.end(),Print);
	 
	 
	 
}
int main()
{
	Vector();
	return 0;
} 

九、vector存放自定义数据类型

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

//自定义数据类型
class Person {
	public:
		Person(string name, int age)
		{
			a_Name = name;
			a_Age = age;
		}
	string a_Name;
	int a_Age;
}; 
//存放对象 
void Vector1()
{
	//创建容器 
	vector<Person> v;
	
	Person p1("a",1);
	Person p2("b",2);
	Person p3("c",3);
	Person p4("d",4);
	Person p5("e",5);
	
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);
	
	for(vector<Person>::iterator it = v.begin();it != v.end();it++)
	{
		cout<< "Name: "<<it->a_Name<<" Age:"<<(*it).a_Age<<endl;
	}
}
//存放对象指针
void Vector2()
{
	//创建容器 
	vector<Person*> v;
	
	Person p1("a",1);
	Person p2("b",2);
	Person p3("c",3);
	Person p4("d",4);
	Person p5("e",5);
	
	v.push_back(&p1);
	v.push_back(&p2);
	v.push_back(&p3);
	v.push_back(&p4);
	v.push_back(&p5);
	
	for(vector<Person*>::iterator it = v.begin();it != v.end();it++)
	{
		Person* p = (*it);
		cout<< "Name: "<<p->a_Name<<" Age:"<<(*p).a_Age<<endl;
	}
} 
int main()
{
	Vector1();
	Vector2();
	return 0;
} 

十、vector容器嵌套容器

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

void Vector1()
{
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;
	vector<int> v4;
	
	for(int i=0;i< 4;i++)
	{
		v1.push_back(i + 1);
		v2.push_back(i + 2);
		v3.push_back(i + 3);
		v4.push_back(i + 4);
	}
	//容器嵌套
	vector<vector<int>> v;
	//子容器元素插入
	v.push_back(v1); 
	v.push_back(v2); 
	v.push_back(v3); 
	v.push_back(v4); 
	
	//输出
	for(vector<vector<int>>::iterator it = v.begin();it != v.end();it++)
	{
		for(vector<int>::iterator vit = (*it).begin();vit != (*it).end();vit++)
		{
			cout<<*vit<<" ";
		}
		cout<<endl;
	} 
}
void Vector2()
{

} 
int main()
{
	Vector1();
	Vector2();
	return 0;
} 

总结

vector 容器是 STL 中最常用的容器之一,它和 array 容器非常类似,都可以看做是对 C++ 普通数组的“升级版”。不同之处在于,array 实现的是静态数组(容量固定的数组),而 vector 实现的是一个动态数组,即可以进行元素的插入和删除,在此过程中,vector 会动态调整所占用的内存空间,整个过程无需人工干预。
另外vector 提供了许多了成员函数供我们使用,详情可参见下表

函数成员函数功能
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()在序列尾部生成一个元素。

除此之外,C++ 11 标准库还新增加了 begin() 和 end() 这 2 个函数,和 vector 容器包含的 begin() 和 end() 成员函数不同,标准库提供的这 2 个函数的操作对象,既可以是容器,还可以是普通数组。当操作对象是容器时,它和容器包含的 begin() 和 end() 成员函数的功能完全相同;如果操作对象是普通数组,则 begin() 函数返回的是指向数组第一个元素的指针,同样 end() 返回指向数组中最后一个元素之后一个位置的指针(注意不是最后一个元素)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七七高7777

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值