C++标准模版库STL之Vector容器

C++中容器的定义

数据存储上,有一种对象类型,它可以持有其他对象或指向其他对象的指针,这种对象类型叫容器。通俗地说容器就是保存其他对象的对象,这种“对象”还包含了一些处理其他对象的方法,这也体现了容器类的一个好处,“容器类是一种对特定代码重用问题的良好的解决方案”。容器另一个好处就是可以自行扩展,解决问题时通常不知道需要存储多少个对象,数组在这方面也是力不从心。容器可以申请内存、释放内存,并且使用最优的算法来执行命令。

顺序容器

顺序容器是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。顺序容器具有插入速度快但查找操作相对较慢的特征。

C++标准模板库里提供3种顺序容器:vector、list和deque。其中,vector类和deque类是以数组为基础的,list类是以双向链表为基础的。

向量(vector)又可以称作变长数组

vector是一个动态的顺序容器,具有连续内存地址的数据结构,通过下标运算符“[]”直接有效地访问向量的任何元素。相比于数组,vector会消耗更多的内存以有效地动态增长。而相比于其他序列容器(deques,lists),vector能更快地索引元素(就像数组一样),而且能相对高效地在尾部插入和删除元素。如果不是在尾部插入和删除元素,效率就没有这些容器高。vector可以用来以邻接表的方式储存图

注:
当需要使用vector的时候,需要包含头文件:#include < vector >,一般加上“using namespace std;”,如果不加,则在调用时候必须用std::vector<…>这样的形式,即在vector前加上std::,这表示运用的是std命名空间下的vector容器。

1、向量的声明及初始化

vector类包含了多个构造函数,其中包括默认构造函数,因此可以通过多种方式来声明和初始化向量容器。
在这里插入图片描述
其中元素类型可以是任何基本类型,如int,double,char,结构体…
在这里插入图片描述

2、元素的输入及访问

实例C++代码:

#include<iostream>
#include<vector>

using namespace std;

int main()
{
	vector<int> a(10, 1);
	int i;
	cout << "初始化变量:";
	for(i = 0; i < a.size(); i++)
		cout << a[i] << " ";
	cout << "\n插入数据:";
	cin >> a[2];
	cin >> a[5];
	cin >> a[8];
	for(i = 0; i < a.size(); i++)
		cout << a[i] << " ";
		
	cout << endl;
	return 0;	
} 

本例先用vector类创建一个大小为10初值为1的向量容器a,然后遍历出该容器,接着在容器第3、第6和第9个元素的位置插入三个新元素

运行结果如下:
在这里插入图片描述

3、修改元素

在这里插入图片描述
例如:
在这里插入图片描述
所有的容器都包含成员函数begin()和end()。函数begin()返回容器中第1个元素的位置,函数end()返回容器中伪元素地址的下一个地址。这两个函数都没有参数。
在这里插入图片描述

4、vector容器内元素的访问

(1)通过下标访问
前面已经用代码展示过了,这里就不详细讲了
(2)通过迭代器访问
样例C++代码如下:

#include<stdio.h>
#include<vector>

using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 5; i++){
		vi.push_back(i);
	} 
	
	vector<int>::iterator it = vi.begin();
	for(int i = 0; i < 5; i++)
	{
		printf("%d ", *(it + i));
	} 
	return 0;
}

运行结果如下:
在这里插入图片描述
也可用自加++方法实现上图

#include<stdio.h>
#include<vector>

using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 5; i++){
		vi.push_back(i);
	}
	
	for(vector<int>::iterator it = vi.begin(); it != vi.end(); it++)
		printf("%d ", *it);
	//vector也支持it < vi.end()写法 
	return 0;
}

运行结果和上图一样

vector类包含了一个typedef iterator,这是一个public成员。通过iterator,可以声明向量容器中的迭代器。例如,声明一个向量容器迭代器:
在这里插入图片描述
因为iterator是一个定义在vector类中的typedef,所以必须使用容器名(vector)、容器元素类型和作用域符来使用iterator。
表达式:++it,表示将迭代器it加1,使其指向容器中的下一个元素。
表达式:*it,表示返回当前迭代器位置上的元素。

注意:实际上迭代器就是一个指针,用来存取容器中的数据元素,因此迭代器上的操作和指针上的相应操作是相同的。

在这里插入图片描述
在这里插入图片描述

5、vector常用函数push_back()

push_back(x)就是在vector后面添加一个元素x,时间复杂度为O(1)

#include<stdio.h>
#include<vector>
using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i);
	
	for(int i = 0; i < vi.size(); i++)
	{
		printf("%d ", vi[i]);
	}
	return 0;
} 

运行结果如下:
在这里插入图片描述

6、vector常用函数pop_back()

pop_back()是用来删除vector的尾元素,时间复杂度为O(1)

#include<stdio.h>
#include<vector>

using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i);
	
	vi.pop_back();
	for(int i = 0; i < vi.size(); i++)
		printf("%d ", vi[i]);
	return 0;
}

运行结果如下:
在这里插入图片描述

7、vector常用函数size()

size()就是用来获取vector中元素个数

#include<stdio.h>
#include<vector>
using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i);
		
	printf("%d\n", vi.size()); 
	return 0;
}

运行结果如下:
在这里插入图片描述

8、vector常用函数clear()

clear()用来清空vector中所有元素,时间复杂度为O(N)

#include<stdio.h>
#include<vector>

using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 3; i++)
		vi.push_back(i);
	vi.clear();
	printf("%d\n", vi.size());
	return 0;
}

运行结果如下:
在这里插入图片描述

9、vector常用函数insert()

insert(it, x)用来向vector的任意迭代器it处插入一个元素x,时间复杂度为O(N)

#include<stdio.h>
#include<vector>
using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 1; i <= 5; i++)
		vi.push_back(i);
	
	vi.insert(vi.begin() + 2, -1);
	for(int i = 0; i < vi.size(); i++)
		printf("%d ", vi[i]);
	return 0;
}

运行结果如下:
在这里插入图片描述

10、vector常用函数erase()

(1)删除单个元素
erase(it)为删除迭代器为it处的元素

#include<stdio.h>
#include<vector>
using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 5; i <= 9; i++)
		vi.push_back(i);
	
	vi.erase(vi.begin() + 3);
	for(int i = 0; i < vi.size(); i++)
		printf("%d ", vi[i]);
	return 0;
}

运行结果如下:
在这里插入图片描述
(2)删除一个区间内的所有元素
erase(first, last)为删除[first, last)内的所有元素

#include<stdio.h>
#include<vector>

using namespace std;

int main()
{
	vector<int> vi;
	for(int i = 5; i <= 9; i++)
		vi.push_back(i);
	
	vi.erase(vi.begin() + 1, vi.begin() + 4);
	
	for(int i = 0; i < vi.size(); i++)
		printf("%d ", vi[i]);
	printf("\n");
	return 0;	
} 

运行结果如下:
在这里插入图片描述

二维向量

与数组相同,向量也可以增加维数。例如,声明一个m*n大小的二维向量方式可以像如下形式:
在这里插入图片描述
vector< vector< int > >name;
vector< typename > Arrayname[arraySize];
以上这两种都表示二维数组,但是后者的一维长度已经固定为arraySize,另一维才是变长的

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

int main()
{
	vector< vector<int> > a(3, vector<int>(4, 0));
	cout << "输入:" << endl;
	cin >> a[0][1];
	cin >> a[1][0];
	cin >> a[2][3];
	cout << "输出:" << endl;
	int m, n;
	for(m = 0; m < a.size(); m++)
	{
		for(n = 0; n < a[m].size(); n++)
		{
			cout << a[m][n] << " ";
		}
		cout << '\n';
	} 
	return 0;
} 

运行结果如下:
在这里插入图片描述
分析:使用vector类声明了一个3行4列的二维向量容器,并且初始化值为0。最后同二维数组类似,为其赋值,并输出

综合案例:

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

int main()
{
	int i = 0;
	vector<int> a;
	for(i = 0; i < 10; i++)
	{
		a.push_back(i);
	}
	cout << "初始化遍历:";
	for(int i = 0; i < a.size(); i++)
	{
		cout << a[i] << " ";
	}
	cout << "\n迭代遍历:";
	vector<int>::iterator it;
	for(it = a.begin(); it != a.end(); it++)
	{
		cout << *it << " "; 
	}
	cout << "\n插入遍历:";  
	a.insert(a.begin() + 4, 0);
	for(unsigned int i = 0; i < a.size(); i++)
	{
		cout << a[i] << " ";
	}
	cout << "\n擦除遍历:";
	a.erase(a.begin() + 2);
	for(unsigned int i = 0; i < a.size(); i++)
	{
		cout << a[i] << " ";
	}
	cout << "\n迭代遍历:";
	a.erase(a.begin() + 3, a.begin() + 5);
	for(vector<int>::iterator it = a.begin(); it != a.end(); it++)
	{
		cout << *it << " ";
	} 
	cout << endl;
	return 0;
} 

运行结果如下:
在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值