STL--vector容器

目录

一、C++中vector容器的介绍

二、vector容器的基本概念

1. 定义

2. 功能

3. vector和普通数组的区别

4. 动态扩展 

5. 图形展示

6. 特别

三、vector容器的基本使用方法 

        ​​​​​​​ 1. vector容器遍历内置数据类型

2. vector容器遍历自定义数据类型

3. vector容器的嵌套使用 

四、vector构造函数

五、vector赋值操作

 六、vector容量和大小

 七、vector插入和删除

 八、vector数据存取

 九、互换容器

互换容器

 实际应用

十、vector预留空间


一、C++中vector容器的介绍

 std::vector   是 C++ 标准库中的一个动态数组容器,提供了动态大小的数组功能,可以在运行时动态地增加或减少元素数量。下面是关于   std::vector   的介绍和特点:

1. 动态数组
          std::vector   实际上是一个封装了动态数组的类模板。它可以在运行时根据需要动态增长或缩小,不像静态数组需要在定义时确定大小。

2. 头文件
          std::vector   定义在   <vector>   头文件中,使用时需要包含这个头文件:  #include <vector>  

3. 元素访问
           可以使用下标   []   运算符或   at()   函数访问元素。
           提供了迭代器(iterator)来遍历容器中的元素。

4. 动态扩展
           当向   std::vector   添加元素时,如果空间不足,它会自动分配更多的内存以容纳新的元素,通常是以当前容量的两倍进行扩展,这样可以减少频繁分配内存的开销。

5. 容器大小
           可以使用   size()   函数获取当前   std::vector   中的元素数量。
           可以使用   capacity()   函数获取   std::vector   内部实际分配的存储空间大小。

6. 插入和删除元素
           可以使用   push_back()   在尾部添加元素。
           可以使用   pop_back()   移除尾部的元素。
           可以使用   insert()   在指定位置插入元素。
           可以使用   erase()   移除指定位置或范围的元素。

7. 内存管理
             std::vector   自动处理内存管理,包括内存分配和释放。
           可以使用   reserve()   预留空间,避免多次重新分配内存。

8. 安全性
           提供了边界检查,对于使用   at()   访问元素的方式,在越界时会抛出   std::out_of_range   异常。

9. 支持移动语义
             std::vector   支持移动语义,可以高效地进行元素的移动和传递。

二、vector容器的基本概念

1. 定义

        vector是C++标准模板库中的部分内容,中文偶尔译作“容器”,但并不准确。它是一个多功能的,能够操作多种数据结构和算法的模板类函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。

2. 功能

        vector数据结构和数组相似,也成为单端数组。

3. vector和普通数组的区别

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

4. 动态扩展 

        并不是在原空间之后续接新空间,而是找到更大的内存空间,然后将原数据拷贝到新空间,释放原空间。

5. 图形展示

6. 特别

        vector容器的迭代器是支持随机访问的迭代器(可以跳跃式访问)。

三、vector容器的基本使用方法 

 1. vector容器遍历内置数据类型

示例:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void print_Vector(vector<int>& v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void myprint(int val)
{
	cout << val << " ";
}
int main()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(30);
	v.push_back(20);
	v.push_back(50);
	v.push_back(60);

	// 以迭代器的方式访问
	vector<int>::iterator itBegin = v.begin();// 指向第一个数
	vector<int>::iterator itEnd = v.end();// 指向的是最后一个数的前一个数
	cout << "第一个数:" << *itBegin << endl;
	cout << "最后一个数:" << *(itEnd - 1) << endl;
	cout << "第一个数:" << *v.begin() << endl;
	cout << "最后一个数:" << *(v.end() - 1) << endl;

	// 第一种遍历方式
	cout << "第一种遍历方式" << endl;
	while (itBegin != itEnd)
	{
		cout << *itBegin << " ";
		itBegin++;
	}
	cout << endl;

	// 第二种遍历方式
	cout << "第二种遍历方式" << endl;
	print_Vector(v);

	// 第三种遍历方式,利用algorithm 头文件包含的内置算法,需要回调函数
	cout << "第三种遍历方式,利用algorithm 头文件包含的内置算法,需要回调函数" << endl;
	for_each(v.begin(), v.end(), myprint);
	// 最后一个参数是回调函数,一开始不调用,只有for_each调用的时候才调用
	cout << endl << "最后一个参数是回调函数,一开始不调用,只有for_each调用的时候才调用" << endl;
	cout << endl;
	return 0;
}

运行结果:

2. vector容器遍历自定义数据类型

 示例:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class person
{
public:
	person(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
	string name;
	int age;
};
void print_Vector(vector<person>& v)
{
	for (vector<person>::iterator it = v.begin(); it != v.end(); it++)
	{
		// 迭代器返回的类型就是<>内的类型
		cout << "姓名:" << it->name << "\t年龄:" << it->age << endl;
		// 也可以先*it解引用出来后(.)某个属性
		cout << "姓名:" << (*it).name << "\t年龄:" << (*it).age << endl;
	}
}
int main()
{
	// 准备数据
	person p1("张三", 10);
	person p2("李四", 30);
	person p3("王五", 20);
	person p4("赵六", 50);
	person p5("郭七", 60);

	vector<person> v;
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);

	cout << "迭代器返回的类型就是\"<>\"内的类型" << endl;
	cout << "也可以先\"*it\"解引用出来后\".\"某个属性" << endl;
	print_Vector(v);
	return 0;
}

运行结果:

3. vector容器的嵌套使用 

示例:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void print_Vector(vector<vector<int> >& v)
{
	for (vector<vector<int> >::iterator it = v.begin(); it != v.end(); it++)
	{
		for (vector<int>::iterator jt = it->begin(); jt != it->end(); jt++)
		{
			cout << *jt << " ";
		}
		cout << endl;
	}
}
int main()
{
	// 大容器
	vector<vector<int> > v;
	// 小容器
	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);
	}

	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	v.push_back(v4);

	print_Vector(v);
	return 0;
}

运行结果:

 

四、vector构造函数

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

示例: 

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

int main()
{
	// 默认构造,无参构造
	cout << "默认构造,无参构造" << endl;
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	print_Vector(v1);

	// 通过区间方式构造
	vector<int> v2(v1.begin(), v1.end());
	cout << "通过区间方式构造" << endl;
	print_Vector(v2);

	// n个elem的方式
	vector<int>v3(10, 20); // 10个20
	cout << "通过构建n个elem的方式构建vector" << endl;
	print_Vector(v3);

	// 拷贝构造
	vector<int>v4(v3);
	cout << "通过拷贝构造vector" << endl;
	print_Vector(v4);

	return 0;
}

运行结果:

 

 

五、vector赋值操作

  • vector  &  operator=(const  vector  &  vec);     // 重载等号赋值
  • assign(beg,   end);                                        // 将beg,end区间中的数据拷贝赋值给本身
  • assign(n,  elem);                                                // 将n个elem拷贝赋值给本身

示例: 

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

int main()
{
	// 默认构造,无参构造
	vector<int> v1;
	cout << "默认构造,无参构造" << endl;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	print_Vector(v1);

	// 赋值
	vector<int> v2;
	v2 = v1;
	cout << "利用一个已经构建好的vector,直接赋值给另一个vector" << endl;
	print_Vector(v2);

	// assign  区间
	vector<int>v3;
	v3.assign(v1.begin(), v1.end());
	cout << "利用assign  区间对vector进行赋值" << endl;
	print_Vector(v3);

	// n个elem
	vector<int> v4;
	v4.assign(10, 100);
	cout << "利用n个elem对vector进行赋值" << endl;
	print_Vector(v4);

	return 0;
}

运行结果:

 

 

 六、vector容量和大小

  • empty();             // 判断容器是否为空
  • capacity();          // 容器的容量
  • size();                 // 返回容器中元素的个数
  • resize();             // 重新指定容器的长度为num,若容器变长则默认值填充新位置

                                  // 如果容器变短,则末尾超出容器长度的元素被删除

  • resize();            // 重新指定容器的长度为num,若容器变长,则以elem值填充新位置

                                 // 如果容器变短,则末尾超出容器长度的元素被删除

示例: 

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

int main()
{
	// 默认构造,无参构造
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	cout << "默认构造,无参构造" << endl;
	print_Vector(v1);

	// 判断是否为空
	v1.empty();// 判断是否为空,空返回1不空0
	cout << "判断是否为空,判断是否为空,空返回1不空0" << endl;
	cout << v1.empty() << endl;

	// 容量
	int num = v1.capacity();
	cout << "v1容器的容量:" << num << endl;
	// 大小
	int size = v1.size();
	cout << "v1容器的大小:" << size << endl;

	// 重新指定大小
	cout << endl << "重新指定大小" << endl;
	v1.resize(15);
	cout << "比原本的大小大,默认用0填充" << endl;
	print_Vector(v1);// 比原本的大小大,默认用0填充
	v1.resize(7);
	cout << "比原本的大小小,默认删除指定大小后的元素" << endl;
	print_Vector(v1);// 比原本的大小小,默认删除指定大小后的元素

	// 重载版本
	cout << "重新指定大小用指定数字填充" << endl;
	v1.resize(15, 100);// 用100填充
	print_Vector(v1);
	return 0;
}

运行结果:

 

 

 七、vector插入和删除

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

示例: 

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

int main()
{
	// 默认构造,无参构造
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	cout << "默认构造,无参构造" << endl;
	print_Vector(v1);

	// 尾删
	cout << "尾删" << endl;
	v1.pop_back();
	print_Vector(v1);

	// 插入
	cout << "插入vector容器中数据,第一个参数是迭代器" << endl;
	v1.insert(v1.begin(), 100); // 第一个参数是迭代器
	print_Vector(v1);
	cout << "插入vector容器中n个数据,第一个参数是迭代器,第二个参数是个数,第三个参数是插入的数据" << endl;
	// 插入n个数
	v1.insert(v1.begin(), 2, 1000);
	print_Vector(v1);

	// 删除
	cout << "删除迭代器所在位置的数据" << endl;
	v1.erase(v1.begin());// 第一个参数还是迭代器	
	print_Vector(v1);
	// 删除区间
	cout << "删除容器区间内的数据" << endl;
	v1.erase(v1.begin(), v1.end());
	print_Vector(v1);

	// 清空
	cout << "清空vector容器中的数据" << endl;
	v1.clear();
	print_Vector(v1);
	return 0;
}

运行结果:

 

 八、vector数据存取

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

示例: 

#include<iostream>
#include<vector>
using namespace std;
void print_Vector(vector<int>& v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
int main()
{
	// 默认构造,无参构造
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	cout << "默认构造,无参构造" << endl;
	print_Vector(v1);

	// 利用[]
	cout << "利用[]获取数据在vector容器中的位置" << endl;
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	// 利用at
	cout << "利用\".at()\"获取数据在vector容器中的位置" << endl;
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1.at(i) << " ";
	}
	cout << endl;

	// 返回头尾元素
	cout << "第一个元素为(front()):" << v1.front() << endl;
	cout << "最后一个元素为(back()):" << v1.back() << endl;
	return 0;
}

运行结果:

 

 九、互换容器

互换容器

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

示例: 

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

int main()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	cout << "交换前" << endl;
	print_Vector(v1);

	vector<int> v2;
	for (int i = 20; i >= 0; i--)
	{
		v2.push_back(i);
	}
	print_Vector(v2);

	cout << "交换后" << endl;
	v1.swap(v2);
	print_Vector(v1);
	print_Vector(v2);
	return 0;
}

运行结果:

 

 实际应用

开辟一个很大的数组空间后,重新指定一个小一点的空间,开辟的空间不会收缩 

示例: 

#include<iostream>
#include<vector>
using namespace std;
void print_Vector(vector<int> &v)
{
	for(vector<int>::iterator it=v.begin();it!=v.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}
	
int main()
{
	vector<int> v1;
	for(int i=0;i<100000;i++)
	{
		v1.push_back(i);
	}
	cout<<"容量:"<<v1.capacity()<<endl;
	cout<<"大小:"<<v1.size()<<endl;
	v1.resize(3);
	cout<<"重置大小;"<<endl;
	cout<<"容量:"<<v1.capacity()<<endl;
	cout<<"大小:"<<v1.size()<<endl;
	cout<<"收缩空间:"<<endl;
	vector<int>(v1).swap(v1);  // 利用匿名容器实现一个交换
	cout<<"容量:"<<v1.capacity()<<endl;
	cout<<"大小:"<<v1.size()<<endl;
	return 0;
}

运行结果;

 

十、vector预留空间

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

提高效率,在插入大量数据的时候,可以提前预留一个很大的空间,省去开辟空间的时间。

示例: 

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	// 利用reserve()预留空间
	vector<int> v1;
	v1.reserve(100000);
	int num = 0;  // 统计开辟次数
	int *p = NULL;
	for(int i=0;i<100000;i++)
	{
		v1.push_back(i);
		if(p!=&v1[0])
		{
			p=&v1[0];
			num++;
		}
	}
	cout<<"开辟次数 "<<num<<endl;
	return 0;
}

运行结果:

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值