STL_vector容器_1_特性、函数、举例

1.vector容器特性

动态数组,可变数组。
单口容器。
在尾部插入:push_back()
在尾部弹出:pop_back()
在中间插入:insert()

迭代器:v.begin()和v.end()
反向迭代器:v.rbegin()和v.rend()
在这里插入图片描述

2.vector动态增长原理

vector实现了动态增长:当插入新元素的时候,如果空间不足,那么vector会重新申请更大的一块内存空间(默认原始空间大小两倍),将圆空间数据拷贝到新的空间,释放旧空间的数据,再把新元素插入新申请的空间。

2.1.vector内存申请测试

在vector尾部循环插入一个数据,同时观察vector的capacity、size、vector首地址,看变化趋势。

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	vector<int> v1;
	cout<<"初始:cap:"<<v1.capacity()<<",size:"<<v1.size()<<endl;
	for(int i=0;i<65;i++)
	{
		v1.push_back(i); //尾部插入一个数据
		cout<<"cap:"<<v1.capacity()<<",size:"<<v1.size()<<",vector_add:"<<&v1[0]<<endl;
	}
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 04vecto.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
初始:cap:0,size:0
cap:1,size:1,vector_add:0x55f450486280
cap:2,size:2,vector_add:0x55f4504862a0
cap:4,size:3,vector_add:0x55f450486280
cap:4,size:4,vector_add:0x55f450486280
cap:8,size:5,vector_add:0x55f4504862c0
cap:8,size:6,vector_add:0x55f4504862c0
cap:8,size:7,vector_add:0x55f4504862c0
cap:8,size:8,vector_add:0x55f4504862c0
cap:16,size:9,vector_add:0x55f4504862f0
cap:16,size:10,vector_add:0x55f4504862f0
cap:16,size:11,vector_add:0x55f4504862f0
cap:16,size:12,vector_add:0x55f4504862f0
cap:16,size:13,vector_add:0x55f4504862f0
cap:16,size:14,vector_add:0x55f4504862f0
cap:16,size:15,vector_add:0x55f4504862f0
cap:16,size:16,vector_add:0x55f4504862f0
cap:32,size:17,vector_add:0x55f450486340
cap:32,size:18,vector_add:0x55f450486340
cap:32,size:19,vector_add:0x55f450486340
cap:32,size:20,vector_add:0x55f450486340
cap:32,size:21,vector_add:0x55f450486340
cap:32,size:22,vector_add:0x55f450486340
cap:32,size:23,vector_add:0x55f450486340
cap:32,size:24,vector_add:0x55f450486340
cap:32,size:25,vector_add:0x55f450486340
cap:32,size:26,vector_add:0x55f450486340
cap:32,size:27,vector_add:0x55f450486340
cap:32,size:28,vector_add:0x55f450486340
cap:32,size:29,vector_add:0x55f450486340
cap:32,size:30,vector_add:0x55f450486340
cap:32,size:31,vector_add:0x55f450486340
cap:32,size:32,vector_add:0x55f450486340
cap:64,size:33,vector_add:0x55f4504863d0
cap:64,size:34,vector_add:0x55f4504863d0
cap:64,size:35,vector_add:0x55f4504863d0
cap:64,size:36,vector_add:0x55f4504863d0
cap:64,size:37,vector_add:0x55f4504863d0
cap:64,size:38,vector_add:0x55f4504863d0
cap:64,size:39,vector_add:0x55f4504863d0
cap:64,size:40,vector_add:0x55f4504863d0
cap:64,size:41,vector_add:0x55f4504863d0
cap:64,size:42,vector_add:0x55f4504863d0
cap:64,size:43,vector_add:0x55f4504863d0
cap:64,size:44,vector_add:0x55f4504863d0
cap:64,size:45,vector_add:0x55f4504863d0
cap:64,size:46,vector_add:0x55f4504863d0
cap:64,size:47,vector_add:0x55f4504863d0
cap:64,size:48,vector_add:0x55f4504863d0
cap:64,size:49,vector_add:0x55f4504863d0
cap:64,size:50,vector_add:0x55f4504863d0
cap:64,size:51,vector_add:0x55f4504863d0
cap:64,size:52,vector_add:0x55f4504863d0
cap:64,size:53,vector_add:0x55f4504863d0
cap:64,size:54,vector_add:0x55f4504863d0
cap:64,size:55,vector_add:0x55f4504863d0
cap:64,size:56,vector_add:0x55f4504863d0
cap:64,size:57,vector_add:0x55f4504863d0
cap:64,size:58,vector_add:0x55f4504863d0
cap:64,size:59,vector_add:0x55f4504863d0
cap:64,size:60,vector_add:0x55f4504863d0
cap:64,size:61,vector_add:0x55f4504863d0
cap:64,size:62,vector_add:0x55f4504863d0
cap:64,size:63,vector_add:0x55f4504863d0
cap:64,size:64,vector_add:0x55f4504863d0
cap:128,size:65,vector_add:0x55f4504864e0

结果分析(自我理解):
vector初始capacity和size都是0;
在一个个向尾部添加数据后,当vector空间不足以存储数据时,申请更大的空间以存储新插入的数据。申请空间的总大小为当前空间大小的两倍。
当申请更大空间时,首地址发生变化:说明存储位置是全新的,不是在原来的数组尾部地址后面扩展(无法确定尾部后面地址空间是否已经被其他数据占用,干脆重新申请一块两倍大小的空间,让系统自己去分配地址)。

3.vector初始化

3.1.vector构造函数

vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end()); //将v[begin(), end()]区间中的元素拷贝给本身
vector(n, elem); //构造函数将n个elem拷贝给本身
vector(const vector &vec); //拷贝构造函数

例子:使用第二个构造函数,可以

int arr[] = {2,3,4,1,9};
vector<int> v1(arr, arr+sizeof(arr)/sizeof(int));

3.2.vector初始化举例

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

//打印vector中元素
void printvector(vector<int>& v)
{
	for(vector<int>::iterator it = v.begin();it != v.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}

//初始化
int main()
{
	vector<int> v1; //默认构造函数
	
	int arr[] = {10,20,30,40};
	vector<int> v2(arr,arr+sizeof(arr)/sizeof(int));
	vector<int> v3(v2.begin(), v2.end());
	vector<int> v4(v3);
	
	printvector(v2);
	printvector(v3);
	printvector(v4);
	
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
10 20 30 40
10 20 30 40
10 20 30 40

4.vector常用赋值操作

4.1.vector赋值操作函数

assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem); //将n个elem拷贝赋值给本身。
vector& operator=(const vector &vec); //重载等号操作符
swap(vec); //将vec与本身的元素互换

4.2.vector赋值操作函数举例

#include <iostream>
#include <vector> //vector需要包含的头文件

using namespace std;
void printvector(vector<int>& v)
{
	for(vector<int>::iterator it = v.begin();it != v.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}

//初始化
int main()
{
	int arr[] = {10,20,30,40};
	//构造函数
	vector<int> v1(arr,arr+sizeof(arr)/sizeof(int));
	//成员方法
	vector<int> v2;
	v2.assign(v1.begin(), v1.end());
	//重载=
	vector<int> v3;
	v3 = v2;

	int arr1[] = {100,200,300,400};
	vector<int> v4(arr1, arr1+sizeof(arr1)/sizeof(int));
	cout<<"======互换前打印======"<<endl;
	printvector(v1);
	printvector(v2);
	printvector(v3);
	printvector(v4);
	
	//互换元素,注意不是赋值
	v4.swap(v1); 

	cout<<"======互换后打印======"<<endl;
	printvector(v1);
	printvector(v2);
	printvector(v3);
	printvector(v4);

	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 02vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
======互换前打印======
10 20 30 40
10 20 30 40
10 20 30 40
100 200 300 400
======互换后打印======
100 200 300 400
10 20 30 40
10 20 30 40
10 20 30 40

5.vector大小操作

5.1.vector大小操作函数

size(); //返回容器中元素个数
empty(); //判断容器是否为空
resize(int  num); //重新指定容器的长度num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
capacity(); //容器的容量
reserve(int len); //容器预留一个len个元素长度,预留位置不初始化,元素不可访问。

5.2.vector大小操作函数举例

#include <iostream>
#include <vector> //vector需要包含的头文件

using namespace std;
void printvector(vector<int>& v)
{
	for(vector<int>::iterator it = v.begin();it != v.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}

//初始化
int main()
{
	int arr[] = {10,20,30,40};
	vector<int> v2(arr,arr+sizeof(arr)/sizeof(int));
	cout<<"size:"<<v2.size()<<endl;
	if(v2.empty())
	{
		cout<<"空!"<<endl;
		return 0;
	}
	else
	{
		cout<<"非空!"<<endl;
	}
	cout<<"v2:";
	printvector(v2);
	
	v2.resize(2);
	cout<<"v2.resize(2):";
	printvector(v2);

	v2.resize(6);
	cout<<"v2.resize(6):";
	printvector(v2);
	
	v2.resize(8,1);
	cout<<"v2.resize(8,1):";
	printvector(v2);
	
	cout<<"v2.size():"<<v2.size()<<endl;
	cout<<"v2.capacity():"<<v2.capacity()<<endl;

	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 03vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
size:4
非空!
v2:10 20 30 40
v2.resize(2):10 20
v2.resize(6):10 20 0 0 0 0
v2.resize(8,1):10 20 0 0 0 0 1 1
v2.size():8
v2.capacity():12

6.vector数据存取操作

6.1.vector存取操作函数

at(int idx); //返回索引idx所指的数据,如果idx越界,跑出out_of_range异常。
operator[]; //返回索引idx所指的数据,越界时,运行直接报错。
front(); //返回容器中第第一个数据元素
back(); //返回容器中最后一个数据元素

6.2.vector存取举例

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	int arr[] = {10,20,30,40};
	vector<int> v1(arr,arr+sizeof(arr)/sizeof(int));
	//v.at(i)成员函数
	cout<<"v.at(i):";
	for(int i=0;i<v1.size();i++)
	{
		cout<<v1.at(i)<<" ";
	}
	cout<<endl;
	//v[i],[]运算符
	cout<<"v[i]:";
	for(int i=0;i<v1.size();i++)
	{
		cout<<v1[i]<<" ";
	}
	cout<<endl;
	//v.front()成员函数
	cout<<"v.front():"<<v1.front()<<endl;
	//v.back()成员函数
	cout<<"v.back():"<<v1.back()<<endl;
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 04vecto.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
v.at(i):10 20 30 40
v[i]:10 20 30 40
v.front():10
v.back():40

7.vector插入和删除操作

7.1.vector插入和删除函数

insert(const_iterator pos, int count,ele); //向迭代器指向位置pos插入count个元素ele
push_back(ele); //尾部插入元素ele
pop_back(); //删除最后一个元素
erase(const_iterator start,const_iterator end); //删除迭代器从start到end之间的元素,不包括end
erase(const_iterator pos); //删除迭代器指向的元素
clear(); //删除容器中所有元素

7.2.vector插入删除举例

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

void printvector(vector<int>& v)
{
	for(vector<int>::iterator it = v.begin();it != v.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}

int main()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	//使用迭代器插入
	v.insert(v.begin(),30);
	v.insert(v.end(),40);
	printvector(v);
	//支持数组下标,一般都支持随机访问
	//vector迭代器可以直接+2,+3,-1操作
	v.insert(v.begin()+2,100); 
	printvector(v);
	//删除
	v.erase(v.begin()); //删除单个元素
	printvector(v);
	v.erase(v.begin()+1,v.end()); //删除整个区间元素
	printvector(v);
	//清空
	v.clear();
	cout<<"size:"<<v.size()<<endl;
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 05vecto.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
30 10 20 40
30 10 100 20 40
10 100 20 40
10
size:0

8.巧用swap收缩vector空间

8.1.resize()减小vector后,capacity是否减小?

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	vector<int> v; 
	for(int i=0;i<10000;i++)
	{
		v.push_back(i);
	}
	cout<<"resize前:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	v.resize(10);
	cout<<"resize后:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 06vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
resize前:capacity:16384,size:10000
resize后:capacity:16384,size:10

执行结果分析:
resize减少了vector元素个数,但是capacity并没有随着减小,占用了不必要的空间。

8.2.巧用swap收缩vector空间

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	vector<int> v; 
	for(int i=0;i<10000;i++)
	{
		v.push_back(i);
	}
	cout<<"resize前:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	v.resize(10);
	cout<<"resize后:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	//收缩空间,交换
	vector<int>(v).swap(v);
	cout<<"swap后:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 06vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
resize前:capacity:16384,size:10000
resize后:capacity:16384,size:10
swap后:capacity:10,size:10

结果分析:

vector<int>(v).swap(v);

vector<int>声明的无名对象,使用v去初始化无名对象,然后对无名对象调用swap()函数,和v互换。无名对象使用完后自动释放。

8.3.上例swap收缩vector空间的另一种拆分写法

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	vector<int> v; 
	for(int i=0;i<10000;i++)
	{
		v.push_back(i);
	}
	cout<<"resize前:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	v.resize(10);
	cout<<"resize后:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	//收缩空间
	vector<int> v_tmp(v);
	cout<<"swap前:v_tmp.capacity:"<<v_tmp.capacity()<<",v_tmp.size:"<<v_tmp.size()<<endl;
	v_tmp.swap(v);
	cout<<"swap后:capacity:"<<v.capacity()<<",size:"<<v.size()<<endl;
	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 06vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
resize前:capacity:16384,size:10000
resize后:capacity:16384,size:10
swap前:v_tmp.capacity:10,v_tmp.size:10
swap后:capacity:10,size:10

9.reserve预留空间提高效率

9.1.如果不使用reserve,重新申请空间次数

在vector尾部逐个添加元素,查看vector自动重新申请空间的次数。

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	vector<int> v; 
	int* v_add = NULL;
	int num;
	for(int i=0;i<10000;i++)
	{
		v.push_back(i);
		if(v_add != &(v[0]))
		{
			cout<<"add["<<i<<"]:"<<&(v[0]<<endl;
			v_add = &v[0];
			num ++;
		}
	}
	cout<<"num:"<<num<<endl;

	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 07vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
add[0]:0x564d1ec4ae70
add[1]:0x564d1ec4b2a0
add[2]:0x564d1ec4ae70
add[4]:0x564d1ec4b2c0
add[8]:0x564d1ec4b2f0
add[16]:0x564d1ec4b340
add[32]:0x564d1ec4b3d0
add[64]:0x564d1ec4b4e0
add[128]:0x564d1ec4b6f0
add[256]:0x564d1ec4bb00
add[512]:0x564d1ec4c310
add[1024]:0x564d1ec4d320
add[2048]:0x564d1ec4f330
add[4096]:0x564d1ec53340
add[8192]:0x564d1ec5b350
num:15

9.1.如果使用reserve预留空间,不需要重新申请

预留足够空间后,空间足够使用,所以不需要再一次次申请。

#include <iostream>
#include <vector> //vector需要包含的头文件
using namespace std;

int main()
{
	vector<int> v; 
	int* v_add = NULL;
	int num;
	v.reserve(10000);
	for(int i=0;i<10000;i++)
	{
		v.push_back(i);
		if(v_add != &(v[0]))
		{
			cout<<"add["<<i<<"]:"<<&v[0]<<endl;
			v_add = &v[0];
			num ++;
		}
	}
	cout<<"num:"<<num<<endl;

	return 0;
}

执行结果:

root@host:/home/LinuxShare/007.STL# g++ 07vector.cpp
root@host:/home/LinuxShare/007.STL# ./a.out
add[0]:0x556c13abde70
num:1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值