[C++]STL-vector容器

vector容器(动态数组,可变数组)

单口容器

在这里插入图片描述

vector动态增长的基本原理

当插入新元素时,如果空间不足,那么vector会重新申请更大的一块内存空间,将原来空间拷贝到新空间上,释放旧空间的数据,再把新元素插入新申请的空间。

默认会申请两倍的新空间,但当空间达到一定大小时,会动态调整其增长策略

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

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

//初始化方法
void VectorTest1() {
	vector<int> v1;  //默认构造
	int arr[] = { 10,20,30 };
	vector<int> v2(arr, arr + sizeof(arr) / sizeof(int));  //含参构造,第一个参数是容器开始位置,第二个参数是容器结束位置
	vector<int> v3(v2.begin(),v2.end());
	vector<int> v4(v3); //拷贝构造
	PrintVector(v4);
}

//常用赋值操作
void VectorTest2() {
	int arr[] = { 10,20,30 };
	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 };
	vector<int> v4(arr1, arr1 + sizeof(arr) / sizeof(int));
	//交换函数的本质是指针的交换
	v4.swap(v1);
	cout << "v1" << endl;
	PrintVector(v1);
	cout << "v2" << endl;
	PrintVector(v2);
	cout << "v3" << endl;
	PrintVector(v3);
	cout << "v4" << endl;
	PrintVector(v4);
	//可以看到,只是赋值,并没有跟随原数据交换而改变
}


int main() {
	VectorTest2();

	return 0;
}

vector大小操作

#include<iostream>
#include<vector>
using namespace std;
void PrintVector1(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << "the val is " << *it << endl;
	}
}

void vector1() {
	int arr[] = { 10,20,30 };
	vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
	int num = v1.size();  //返回容器中元素的个数
	cout << "v1的大小为:" << num << endl;
	if (v1.empty()) {   //判断容器是否为空
		cout << "v1容器是空的" << endl;
	}
	else {
		cout << "v1容器不是空的" << endl;
	}
	v1.resize(5, 66);   //重新指定容器大小,变短则删除多余数据
	//只写一个参数时,变长以默认值填充,两个参数时,以第二个参数填充
	PrintVector1(v1);
	v1.resize(7);
	int num2 = v1.size();  //返回容器中元素的个数
	cout << "v1的新大小为:" << num2 << endl;
	PrintVector1(v1);


	cout << "v1的容量是:"<<v1.capacity() << endl;  //capacity函数获取数组容量
	//size表示元素个数,capacity表示能容纳最多的元素,容量一定大于等于size

}

int main() {
	vector1();

	return 0;
}

vector存取数据操作

#include<iostream>
#include<vector>
using namespace std;
void PrintVector2(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << "the val is " << *it << endl;
	}
}
//vector数据存取
void vectorTest4(){
	int arr[] = { 10,20,30 };
	vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
	for (int i = 0; i < v1.size(); i++) {
		cout << v1[i] << endl;
	}
	for (int i = 0; i < v1.size(); i++) {
		cout << v1.at(i) << endl;
	}
	//两种区别,at在越界时会抛出异常,[]越界时不会抛出异常,直接报错

	cout << "第一个元素是:"<<v1.front() << endl;  //获取容器第一个数据元素
	cout <<"最后一个元素是:"<< v1.back() << endl;  //获取容器最后一个数据元素


}
 

//vector插入和删除
void vectorTest5() {
	vector<int> v;
	v.push_back(56);  //像容器末尾加入一个元素
	v.push_back(6);
	v.push_back(12);
	v.pop_back(); //从元素末尾删除一个元素

	//头插法,把数据插入到容器头部
	v.insert(v.begin(), 199);  //insert函数用来插入数据到指定位置,第一个传入的数据格式是迭代器
	v.insert(v.end(), 250);
	v.insert(v.begin() + 2, 50);  //vector容器支持随机访问,所以可以通过+2访问容器内部元素
	//一般支持[]数组下标访问的,都支持随机访问
	//不支持随机访问的,只能通过++,或+1,不断遍历得到目标元素

	PrintVector2(v);
	cout << "----------------------------" << endl;
	v.erase(v.begin());  //删除指定元素,参数格式是迭代器
	v.erase(v.begin() + 1, v.begin() + 3);  //删除指定区间元素,取左留右
	PrintVector2(v);
	cout << "----------------------------" << endl;

	v.clear();  //清空容器内元素
	cout << "the size of v is " << v.size() << endl;
}

int main() {
	vectorTest5();
	return 0;
}

巧用swap缩减空间

//巧用swap缩减空间
//vector 在空间不足时会自动增加,但是在删除元素时,并不会自动减少
void vectorTest6() {
	vector<int> v;
	for (int i = 0; i < 10000; i++) {
		v.push_back(i);
	}
	cout << "当前v内元素有" << v.size() << "个,容量为 " <<v.capacity() << endl;
	v.resize(10);
	cout << "删除后v内元素有" << v.size() << "个,容量为 " << v.capacity() << endl;
	//可以看到虽然调整了大小,可是容量没有变,浪费空间
	//所以利用swap巧妙缩减空间,前一个v可以按照后一个v的size初始化大小,而后一个v在交换后名存实亡
	vector<int>(v).swap(v);
	cout << "调整大小后v内元素有" << v.size() << "个,容量为 " << v.capacity() << endl;


}

reserve预留空间提高程序效率

reserve和resize区别:

reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。

resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了

void ReverseTest() {
	//reserve预留空间
	int num = 0;  //用来记录申请与释放次数
	int* address = NULL;  //用来记录容器内元素首地址
	vector<int> v;
	v.reserve(10000);    //预留空间
	for (int i = 0; i < 10000; i++) {
		//判断在增加一万个元素过程中,进行了多少次元素的申请与释放
		v.push_back(i);
		if (address != &(v[0])) {
			/*
			&(v[0])表示容器内首个元素的地址
			元素在申请释放过程中,首地址会发生变化
			所以以此地址为标准判断
			不可以取容器首地址  &v  ,因为申请释放过程中容器地址不变
			*/
			address = &(v[0]);
			num++;
		}
	}
	cout << num << endl;

	/*
	经过对比,用reserve预留空间前需要申请24次内存,
	但是预留后,只需要一次
	所以如果提前知道大致要存储的元素数量,可以用reserve预留空间,优化程序
	*/
}
发布了18 篇原创文章 · 获赞 2 · 访问量 229

猜你喜欢

转载自blog.csdn.net/renboyu010214/article/details/104416913