234-C++STL(vector)

本文详细介绍了C++标准库中的vector容器,包括其底层数据结构、添加、删除、查询操作以及常用方法。重点讲解了push_back、insert、erase、resize等操作的时间复杂度和内存管理。此外,还展示了如何在实际代码中使用vector进行元素的插入、删除、查询以及遍历,并提供了实例代码演示。

1、vector

vector: 向量容器

底层数据结构: 是动态开辟的数组,每次以原来空间大小的2倍进行扩容的

1.1、添加操作

vector<int> vec; 定义一个int类型的vector

vec.push_back(20); 在末尾添加元素 时间复杂度O(1) 有可能导致容器扩容
vec.insert(it, 20); it迭代器指向的位置添加一个元素20 O(n) 有可能导致容器扩容
插入1个元素,元素后边的所有元素都要向后挪动1个位置

扩容示意图如下:

以原来空间大小的2倍进行扩容,开辟空间,还要把原来的对象在新的内存空间上拷贝构造新的对象,再把原来空间上的对象析构掉,然后free原来的空间。
在这里插入图片描述
容器中进行对象的构造和析构,内存的开辟和释放,都是通过容器的空间配置器allocator(负责内存开辟)和deallocator(负责内存释放),construct(对象构造),destroy(对象析构)

1.2、删除操作

删除:
vec.pop_back(); 从末尾删除元素 时间复杂度是O(1) 
vec.erase(it); 删除it迭代器指向的元素
删除后不允许中间空着,从删除点向后的元素都得向前挪动位置 时间复杂度O(n)

在这里插入图片描述

1.3、查询操作

查询:
operator[] 通过下标的随机访问vec[5] 时间复杂度O(1)
iterator迭代器进行遍历
find
for_each
foreach =>是通过iterator来实现的

注意: 对容器进行连续插入或者删除操作(insert/erase),一定要更新迭代器,否则第一次insert或者erase完成,迭代器就失效了

1.4、常用方法介绍

size() 返回容器底层有效元素的个数
empty() 判断容器是否为空

reserve(20)
给vector预留空间的 只给容器底层开辟指定大小的内存空间,并不会添加新的元素

resize(20):
容器扩容用的 不仅给容器底层开辟指定大小的内存空间,还会添加新的元素

swap : 两个容器进行元素交换

1.5、vector代码应用

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

int main()
{
	vector<int> vec;//vector<string> vec; 0 1 2 4 8 16 32 64
	//默认的vector,底层是0个,没有开辟空间
	//vec.reserve(20);//叫做给vector容器预留20个元素空间,但是不开辟元素对象
	//reserve函数:避免在使用vector的过程中频繁让容器做扩容操作

	vec.resize(20);//叫做给vector容器预留20个元素空间,而且还开辟相应的元素对象

	cout << vec.empty() << endl;//是否是空的?是空的返回1,不是空的返回0
	cout << vec.size() << endl; //int()

	for (int i = 0; i < 20; ++i)
	{
		vec.push_back(rand() % 100 + 1);
		//第一次插入1个元素,0扩容到1,第二次插入1个元素,1扩充到2,然后2-4,4-8一直扩容下去
		//vector效率低,扩容太频繁
	}

	cout << vec.empty() << endl;
	cout << vec.size() << endl;


	//vector的operator[]运算符重载函数
	int size = vec.size();
	for (int i = 0; i < size; ++i)
	{
		cout << vec[i] << " ";
	}
	cout << endl;

	//把vec容器中所有的偶数全部删除
	auto it2 = vec.begin();
	while (it2 != vec.end())
	{
		if (*it2 % 2 == 0)
		{
			it2 = vec.erase(it2);	//要想继续使用这个迭代器,就需要更新下!
			//删除,必须提供earse返回值给it2更新,否则会失效
		}
		else
		{
			++it2;//从当前迭代器指向的元素值判断,因为删除后,后面的元素前移了
		}
	}

	//通过迭代器遍历vector容器
	auto it1 = vec.begin();
	for (; it1 != vec.end(); ++it1)//vec.end()是容器末尾元素的后继位置
	{
		cout << *it1 << " ";
	}
	cout << endl;

	//给vector容器中所有的奇数前面都添加一个小于奇数1的偶数 44 45   56 57
	for (it1 = vec.begin(); it1 != vec.end(); ++it1)
	{
		if (*it1 % 2 != 0)
		{
			it1 = vec.insert(it1, *it1 - 1);	//要想继续使用这个迭代器,就需要更新下!
			++it1;//插入后,后面元素向后挪动1个位置,所以要再++一次
		}
	}

	for (it1 = vec.begin(); it1 != vec.end(); ++it1)
	{
		cout << *it1 << " ";
	}
	cout << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ThinkingF

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

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

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

打赏作者

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

抵扣说明:

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

余额充值