STL提供了一组表示容器、迭代器、函数对象和算法的模板。容器是一个与数组类似的单元,可以存储若干个值。这里面都是基于泛型变成,也就是使用函数模板和类模板技术。
里面主要:
顺序性容器:vector、deque、list
关联性容器:set、multiset、map、multimap
顺序容器配适器:stack、queue、priority_queue
以上的容器我们之后会一一介绍它门的基本函数和相关操作算法,比如对容器进行排序、查找等等。
下面我们来介绍第一个比较常用的 vector:
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>
vector的构造函数如下:
vector<Elem> c vector <Elem> c1(c2) vector <Elem> c(n) vector <Elem> c(n, elem) vector <Elem> c(beg,end) c.~ vector <Elem>() | 创建一个空的vector。 复制一个vector。 创建一个vector,含有n个数据,数据均已缺省构造产生。 创建一个含有n个elem拷贝的vector。 创建一个以[beg;end)区间的vector。 销毁所有数据,释放内存。 |
Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。
Vecor模板类函数列表如下,加粗的表示经常使用的:
1.push_back() 在Vector最后添加一个元素
2.pop_back() 移除Vector最后一个元素
3.size() 返回Vector元素数量的大小
4.front() 返回第一个元素
5.back() 返回最末一个元素
6.begin() 返回第一个元素的迭代器
7.end() 返回最末元素的迭代器(译注:实指向最末元素的下一个位置)
8.erase() 删除指定元素 当参数是 v.begin()时返回向量中第0个元素
9.empty() 判断Vector是否为空(返回true时为空)
10.assign() 对Vector中的元素赋值
11.clear() 清空所有元素
12.insert() 插入元素到Vector中
13.capacity() 返回vector所容纳的元素数量(在不重新分配内存的情况下)
14.max_size() 返回Vector所能容纳元素的最大数量(上限)
15.get_allocator() 返回vector的内存分配器
16.resize() 改变Vector元素数量的大小
17.swap() 交换两个Vector
18.reserve() 设置Vector最小的元素容纳数量
19.rbegin() 返回Vector尾部的逆迭代器 反向遍历向量的时候使用
20.rend() 返回Vector起始的逆迭代器 反向遍历向量的时候使用
21.v.at(i) <-------> v[i] 随机的访问某个元素
下面就来介绍上面的十几个比较重要的函数,首先我们先定义一个vector向量 v,然后测试前 5 个函数
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.push_back(1); // 0
v.push_back(2); // 1
v.push_back(3); // 2
v.push_back(4); // 3
cout << "pop_back 前的:" << endl;
for(int i=0; i<v.size(); i++)
{
cout << v[i] << endl;
}
v.pop_back(); // 把最后面的元素删除
cout << "pop_back 后的:" << endl;
for(i=0; i<v.size(); i++)
{
cout << v[i] << endl;
}
cout << "vector的第一个元素是:" << v.front() << endl;
cout << "vector的最后一个元素是:" << v.back() << endl;
return 0;
}
运行结果:
pop_back 前的:
1
2
3
4
pop_back 后的:
1
2
3
vector的第一个元素是:1
vector的最后一个元素是:3
通过下面的例子来介绍begin 、end、erase三个 函数
语法:
iterator begin();
begin()函数返回一个指向当前vector起始元素的迭代器.
iterator end();
end()函数返回一个指向当前vector末尾元素的迭代器.
iterator erase( iterator loc );
iterator erase( iterator start, iterator end );
erase函数要么删作指定位置 loc 的元素,要么删除区间[start, end)的所有元素.返回值是指向删除的最后一个元素的下一位置的迭代器.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
// 定义一个迭代器来遍历向量里面的元素
vector<int>::iterator it;
for( it = v1.begin(); it != v1.end(); it++ )
cout << *it << endl;
cout << "要删除的第一个数据是:" << v1.front() << endl;
v1.erase(v1.begin());
cout << "使用erase把vector的第一个元素删除后的vector" << endl;
for( it = v1.begin(); it != v1.end(); it++ )
cout << *it << endl;
return 0;
}
运行结果:
1
2
3
4
要删除的第一个数据是:1
使用erase把vector的第一个元素删除后的vector
2
3
4
通过下面的例子来介绍empty()、assign()、clear()、insert()、capacity()
语法:
empty() :判断vector里面是否为空,若是空则返回 1 ,否则返回0
void assign( input_iterator start, input_iterator end );
void assign( size_type num, const TYPE &val );
assign() 函数要么将区间[start, end)的元素赋到当前vector,或者赋num个值为val的元素到vector中.这个函数将会先删除vector之前的内容 然后按照参数来给vector赋值
clear():情况vector所有的元素
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );
insert() 函数有以下三种用法:
在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器,
在指定位置loc前插入num个值为val的元素
在指定位置loc前插入区间[start, end)的所有元素 .
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v1;
vector<int>::iterator it;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
if(!v1.empty())
cout << "向量不空" << endl;
else
cout << "向量为空" << endl;
v1.assign(5, 20); // 设置 5 个数据为都 20
cout << "v1.assign(5, 20)执行之后vector里面的值为:" <<endl;
for (int i=0; i<v1.size(); i++)
cout << v1[i] << endl;
v1.clear(); // 清空 vector 所有元素
cout << "执行clear()之后:";
if(!v1.empty())
cout << "向量不空" << endl;
else
cout << "向量为空" << endl;
it = v1.begin();
v1.insert(it, 2, 30);
cout << "v1.insert(it, 2, 30)插入后vector里面的值为:" <<endl;
for(it=v1.begin(); it!=v1.end(); it++)
cout << *it <<endl;
cout << "执行 v1.capacity(),显示vector里面的元素的数量 = " << v1.capacity() << endl;
return 0;
}
运行结果:
向量不空
v1.assign(5, 20)执行之后vector里面的值为:
20
20
20
20
20
执行clear()之后:向量为空
v1.insert(it, 2, 30)插入后vector里面的值为:
30
30
执行 v1.capacity(),显示vector里面的元素的数量 = 5
通过下面的例子来介绍max_size()、resize()、swap()、rbegin()、rend()
max_size():函数返回当前vector所能容纳元素数量的最大值(译注:包括可重新分配内存).
resize( size_type size, TYPE val ):函数改变当前vector的大小为size,且对新创建的元素赋值val
v1.swap(vector &v):函数交换当前v1与v的元素
rbegin():返回Vector尾部的逆迭代器 反向遍历向量使用的
rend():返回Vector起始的逆迭代器 反向遍历向量使用的
<span style="font-size:12px;">#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v1,v2;
vector<int>::iterator it;
vector<int>::reverse_iterator r_it;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v2.push_back(200);
cout << "可容纳的最大元素个数 = " << v1.max_size() << endl;
// 本来有4个元素 1、2、3、4 现在把元素个数扩大到10个,其他 6 个赋值为 100
v1.resize(10, 100); // 函数改变当前vector的大小为size,且对新创建的元素赋值val
cout << "执行v1.resize(10, 100)后打印v1元素:" << endl;
for (int i=0; i<v1.size(); i++)
cout << v1[i] << endl;
cout << "可容纳的最大元素个数 = " << v1.max_size() << endl;
v1.swap(v2);
cout << "执行v1.swap(v2)后打印v1:" << endl;
for (i=0; i<v1.size(); i++)
cout << v1[i] << endl;
cout << "执行v1.swap(v2)后打印v2:" << endl;
for (i=0; i<v2.size(); i++)
cout << v2[i] << endl;
// 使用rbegin() 和 rend函数反向遍历向量
cout << "使用rbegin() 和 rend函数反向遍历向量" <<endl;
for (r_it=v2.rbegin(); r_it!=v2.rend(); r_it++)
cout << *r_it << endl;
return 0;
}
执行结果:
可容纳的最大元素个数 = 1073741823
执行v1.resize(10, 100)后打印v1元素:
1
2
3
4
100
100
100
100
100
100
可容纳的最大元素个数 = 1073741823
执行v1.swap(v2)后打印v1:
200
执行v1.swap(v2)后打印v2:
1
2
3
4
100
100
100
100
100
100
使用rbegin() 和 rend函数反向遍历向量
100
100
100
100
100
100
4
3
2
1
注:工程中一般把vector当做数组使用,你在使用数组时用vector就好了,实现了很方便的管理。
vector的优点:1.可从后面快速的插入与删除 2.直接访问任何元素(使用[]或者at(int 下标)函数)
vector的缺点:如果在序列中间插入,删除元素要比较慢
下一节我们将谈到STL库里面的操作vector的算法。我们以后就这样分类,先讲结构在讲算法。
1.本文部分素材来源网络,版权归原作者所有,如涉及作品版权问题,请与我联系删除。
2.未经原作者允许不得转载本文内容,否则将视为侵权;
3.转载或者引用本文内容请注明来源及原作者;
4.对于不遵守此声明或者其他违法使用本文内容者,本人依法保留追究权等。
下面是我的个人微信公众号,关注【一个早起的程序员】精彩系列文章每天不断。