【STL】vector与deque容器

1. 基本概念

  1. vector容器:本质上就是一个单端数组和动态数组。
    (1)但当原空间的容量不足时,会开辟新空间,将原数据复制到新空间后释放原空间;
    (2)vertor容器并不是进行两倍容量过逐一增加,而是有特定的算法。在这里插入图片描述
  2. vector迭代器:由于vector容器类似于数组,维护的时线性空间,因此普通指针都可以作为vector迭代器。
    (1)vector支持随机存取: 如operaroe*, operator->, operator++, operator--, operator+, operator-, operator+=, operator-=

2. vector容器的构造、赋值、交换

2.1 构造

  1. 构造方式
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem);//构造函数将n个elem拷贝给本身。
vector(const vector &vec);//拷贝构造函数。
  1. 代码实现
void test01()
{
	//1.采用模板实现类实现,默认构造函数vector<T> v
	vector<int> v1;
	//2.构造函数将n个elem拷贝给本身。vector(n, elem);
	vector<int> v2(10, 100);
	myPrint(v2);
	//3.将v[begin(), end())区间中的元素拷贝给本身。vector(v.begin(), v.end());
	vector<int> v3(v2.begin(), v2.end());
	myPrint(v3);
	//4.拷贝构造函数。vector(const vector& vec)
	vector<int>v4(v3);
	myPrint(v3);
}

2.2 赋值与交换

  1. 赋值函数
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
vector& operator=(const vector  &vec);//重载等号操作符
  1. 交换函数
swap(vec);// 将vec与本身的元素互换。
  1. 代码实现
void test02()
{
	//1.assign(n, elem);将n个elem拷贝赋值给本身。
	vector<int> v1;
	v1.assign(10, 100);
	myPrint(v1);
	//2.将n个elem拷贝赋值给本身。assign(n, elem);
	vector<int> v2;
	v2.assign(v1.begin(), v1.end());
	myPrint(v2);
	//3.重载等号操作符vector& operator=(const vector& vec);
	vector<int> v3;
	v3 = v1;
	myPrint(v3);

	//4.交换
	int arr[] = {1, 2, 3, 4, 5};
	vector<int> v4;
	v4.assign(arr, arr + (sizeof(arr) / sizeof(int)));
	myPrint(v4);

	v4.swap(v3);
	myPrint(v3);
	myPrint(v4);
}

3. 常用接口

3.1 大小操作

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

void test03()
{
	//1.创建容器
	int arr[] = {0, 1, 2, 3, 4};
	vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
	//size();//返回容器中元素的个数;empty();判断容器是否为空
	if (v.empty())
	{
		cout << "容器已空" << endl;
	}
	else
	{
		cout << v.size() << endl;
	}
	//resize(int num);重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
	v.resize(10, 100);
	myPrint(v);
	v.resize(3);
	myPrint(v);
}

3.2 数据存取操作

at(int idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
operator[];//返回索引idx所指的数据,越界时,运行直接报错
front();//返回容器中第一个数据元素
back();//返回容器中最后一个数据元素
void test04()
{
	//1.创建容器
	int arr[] = { 0, 1, 2, 3, 4 };
	vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
	//2.at(int idx); 返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
	for (int i = 0; i < v.size(); i++)
	{
		cout << v.at(i) << endl;
		cout << v[i] << endl;
	}
	try 
	{
		cout << v.at(100) << endl;
		cout << v[100] << endl;
	}
	catch (...)
	{
		cout << "wrong" << endl;
	}
	cout << v.front() << endl;
	cout << v.back() << endl;
}

3.3 插入和删除

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之间的元素
erase(const_iterator pos);//删除迭代器指向的元素
clear();//删除容器中所有元素

void test05()
{
	//1.创建容器
	int arr[] = { 0, 1, 2, 3, 4 };
	vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
	//2.insert(const_iterator pos, int count, ele);//迭代器指向位置pos插入count个元素ele.
	v.insert(v.begin(), 3, 100);
	myPrint(v);
	//3.pop_back(ele); //删除最后一个元素
	v.pop_back();
	myPrint(v);
	//4.erase(const_iterator pos);//删除迭代器指向的元素
	v.erase(v.begin());
	myPrint(v);
	//5.erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素
	v.erase(v.begin(), v.end());
	myPrint(v);
	//6.clear();//删除容器中所有元素
	v.assign(arr, arr + (sizeof(arr) / sizeof(int)));
	v.clear();
	myPrint(v);
}

3.4 vector案例

  1. 通过swap收缩容量
  2. 通过reserve减少扩充次数
/*swap函数收缩空间*/
/*reserve预留空间*/
void test06()
{
	vector<int>v;
	v.reserve(100000);
	int* p = NULL;
	int num = 0;
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);
		if (p != &v[0]) 
		{
			p = &v[0];
			num++;
		}
	}
	cout << "num =" <<num << endl;
	v.resize(3);
	cout << v.size() << endl;
	cout << v.capacity() << endl;
	vector<int>(v).swap(v);
	cout << v.size() << endl;
	cout << v.capacity() << endl;
}

3.5 逆序遍历

void test07()
{
	
	vector<int> v;
	for (int i = 0; i < 5; i++)
	{
		v.push_back(i);
	}
	//1.逆序访问
	for (vector<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); rit++)
	{
		cout << *rit << endl;
	}
	//2.判断迭代器
	//如果判断一个容器的迭代器是否支持随机访问
	vector<int>::iterator itBegin = v.begin();
	itBegin++;
	itBegin--;
	itBegin = itBegin + 1;

	list<int>L;
	L.push_back(10);
	L.push_back(10);
	L.push_back(10);

	list<int>::iterator lBegin = L.begin();
	lBegin++;
	lBegin--;
	//lBegin = lBegin + 1; //不支持随机访问
}

4. deque容器

4.1 基本概念

  1. deque与vector容器的区别
    (1)vector容器时单项开口的连续内存空间,而deque容器则是双向开口的连续内存空间,即可以实现在头尾两端分别做元素的插入和删除操作。
    (2)vector容器也可以实现两端插入和删除但效率太低,vector容器的存储方式相当于连续存储的栈,deque容器存储方式相当于连续存储的队列。注意:只是相似,而非相同,因为栈个队列无法遍历在这里插入图片描述
    (3)deque容器没有容量的概念,其存储是连续分段的存储方式,当原存储容量不足时,会在开辟一块内存存储新的数据,但原来数据继续在原来的地址,通过中控其存储各个段的首地址。在这里插入图片描述
  2. deque迭代器也支持随机访问,但其复杂度远高于vector迭代器,因此占用资源贡多,应尽量使用vector容器。

4.2 基本操作

4.2.1 构造函数
deque<T> deqT;//默认构造形式
deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
deque(n, elem);//构造函数将n个elem拷贝给本身。
deque(const deque &deq);//拷贝构造函数。
4.2.2 赋值操作
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
deque& operator=(const deque &deq); //重载等号操作符 
swap(deq);// 将deq与本身的元素互换
4.2.3 大小操作
deque.size();//返回容器中元素的个数
deque.empty();//判断容器是否为空
deque.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
4.2.4 双端插入和删除操作
push_back(elem);//在容器尾部添加一个数据
push_front(elem);//在容器头部插入一个数据
pop_back();//删除容器最后一个数据
pop_front();//删除容器第一个数据
4.2.5 数据存取
at(idx);//返回索引idx所指的数据,如果idx越界,抛出out_of_range。
operator[];//返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错。
front();//返回第一个数据。
back();//返回最后一个数据
4.2.6 插入操作
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
4.2.7 删除操作
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
//1.构造
	deque<int> d1(10, 100);
	deque<int> d2(d1);
	deque<int> d3(d2.begin(), d2.end());
	deque<int> d4;
	//2.赋值
	deque<int> d5;
	d5 = d1;
	deque<int> d6;
	d6.assign(5, 100);
	deque<int> d7;
	d7.assign(d3.begin(), d3.end());
	//交换
	deque<int> d8;
	d8.swap(d7);
	//3.大小操作
	if (d2.empty())
	{
		cout << "空" << endl;
	}
	else
	{
		cout << "deque.size():" << d2.size() << endl;
	}
	d3.resize(10000);
	d3.resize(10000, 10);
	//4.双端插入和删除操作
	d5.push_back(10);
	d6.push_front(10);
	d7.pop_back();
	d1.pop_front();
	//5.数据存取
	for (int i = 0; i < d1.size(); i++)
	{
		cout << d1[i] << endl;
		cout << d1.at(i) << endl;
	}
	try 
	{
		cout << d1[10000000] << endl;
		cout << d1.at(10000000) << endl;
	}
	catch (...)
	{
		cout << "wrong" << endl;
	}
	cout << d2.front() << endl;
	cout << d2.back() << endl;
	//6.插入操作
	d3.insert(d3.begin(), 10, 100);
	d3.insert(d3.begin(), ++d2.begin(), d2.end());

	//7.删除操作
	d5.clear();
	d6.erase(++d6.begin(), --d6.end());
	d6.erase(d6.begin());
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值