STL::vector容器
一. 什么是vector
vector是C++标准模板库中的内容;
功能:像容器一样存放各种类型的对象,是一个存放任意类型的动态数组,能够增加和压缩数据;
vector是一个类模板而不是一种数据类型,故对它的定义,需要指定类型;
优点:当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的。
C++中vector容器,非常有用推荐频繁使用。
二. 数据存储结构
-
vector的扩充机制:按照当前容器的一倍扩充;
vector分配一块连续的内存空间,每次扩充内存空间并不是在原有空间基础上进行叠加,而是重新申请一块更大的内存,并把现有容器中的元素逐个复制,然后销毁旧的内存。
【注】:此时,指向旧内存空间的迭代器已经失效,当操作容器时要及时更新迭代器。
vector数据结构,连续线性存储。
采用3个迭代器_First、_Last、_End指向分配线性空间的不容范围。
迭代器变量声明:
template<class _Ty, class _A= allocator< _Ty>>
class vector
{
…
protected:
iterator _First, _Last, _End;
};
其中,
_First:指向使用空间的头部,
_Last:指向使用空间大小(size)的尾部
_End:指向使用空间容量(capacity)的尾部
1-1示例:
int data[6]={3,5,7,9,2,4};
vector<int>vdata(data, data+6);
vdata.push_back(6);
...
vector初始化时,内存空间大小为6,存放data的6个元素。
当插入第7个元素“6”时,vector利用自己的扩充机制重新申请空间,
数据存放结构如图所示:
分析:
当插入第7个元素,vector原有内存空间不足,于是申请大小为12的内存空间(自增一倍),并将前面已有数据复制到新空间的前部,然后插入第7个元素。
此时_Last迭代器指向最后一个有效元素,
而_End迭代器指向vector的最后有效空间位置。
利用vector的成员函数size可以获得当前vector的大小,此时为7;
利用capacity成员函数获取当前vector的容量,此时为12。
-
2、vector构造函数原型:
template
explicit vector();// 默认构造函数,vector对象为空
explicit vector(size_type n, const T& v = T()); // 创建有n个元素的vector对 //象
vector(const vector& x);
vector(const_iterator first, const_iterator last);
【注】:vector存放的所有对象都是经过初始化的。
如果没有指定存储对象的初始值,则对于内置类型将用0初始化;
对于类类型将调用其默认构造函数进行初始化;
【注】:如果无默认初始构造函数,则此时必须提供元素初始值。
示例:
vector v1; // 创建空容器,其对象类型为string类
vector v2(10); // 创建有10个具有初始值(即空串)的string类对象的 容器
vector v3(5, “hello”); // 创建有5个值为“hello”的string类对象的容 器
vector v4(v3.begin(), v3.end()); // v4是与v3相同的容器(完全复制)
三. 常见函数及其操作
1、vector的成员函数:
bool empty() const; // 如果容器为空,返回true;否则返回false
size_typemax_size() const; // 返回容器能容纳的最大元素个数
size_type size() const; // 返回容器中元素个数
size_type capacity() const;// 容器能够存储的元素个数,
//有:capacity() >= size()
void reserve(size_type n); // 前提capacity() <=n,只会扩增或者不变
void resize(size_type n, T x = T());// 确保返回后,有:size() == n;如果之前 //size()<n,那么用元素x的值补全(若该元素x的类型为自定义类型则会调用构造函数去填充到新空间,原来的对象会被拷贝构造到新空间)。
swap(vector<_TY> m); //能够用来交换双方的first,last,end指针,这一函数可以被用来操作剔除当前容器中多余的空闲空间
vector<object> objevc{object(10),object(20),object(30),object(30)};
objevc.size()// size=4,capacity = 8
objevc.reserve(10000);// size = 4, capacity = 10000
{
vector<object> tmp(objevc);//调用vector的拷贝构造,只拷贝有效数值即size的个数
tmp.swap(objevc)//会交换first,last,end 指针,然后退出代码块之后,tmp指向的大空间会被释放,这样就会有效缩容容器空间
}
reference front();//返回容器中第一个元素的引用(容器必须非空)
reference back(); // 返回容器中最后一个元素的引用(容器必须非空)
reference operator; // 返回下标为pos的元素的引用(下标 //从0开始;如果下标不正确,则属于未 //定义行为。
reference at(size_typepos); // 返回下标为pos的元素的引用;如果下标不正 //确,则抛出异常out_of_range
const_reference at(size_typepos) const;//返回下标为pos的元素
void push_back(const T& x); // 向容器末尾添加一个元素
void pop_back();// 弹出容器中最后一个元素(容器必须非空)
【注】:下面的插入和删除操作将发生元素的移动,故之前的迭代器可能失效。
iterator insert(iterator it, const T& x = T()); // 在插入点元素之前插入元素 //(或者说在插入点插入元素)
void insert(iterator it, size_type n, const T& x); //注意迭代器可能不再有效
void insert(iterator it, const_iterator first, const_iterator last);
iterator erase(iterator it); // 删除指定元素,并返回删除元素后一个元素的位 //置(如果无元素,返回end())
iterator erase(iterator first, iterator last); //删除元素后,删除点之后的元素对 //应的迭代器不再有效。
void clear() const; // 清空容器,相当于调用erase( begin(), end())
void assign(size_type n, const T& x = T());// 赋值,用指定元素序列替换容器 //内所有元素
void assign(const_iterator first, const_iterator last);
const_iterator begin() const; // 迭代序列
iterator begin();
const_iterator end() const;
iterator end();
【注】:任何改变容器大小的操作都可能造成以前的迭代器失效。
const_reverse_iteratorrbegin() const;
reverse_iteratorrbegin();
const_reverse_iterator rend() const;
reverse_iterator rend();
2、vector对象的比较:(非成员函数)
有六个比较运算符:
operator==、
operator!=、
operator<、
operator<=、
operator>、
operator>=。
其中,
operator==和operator!=:如果vector对象拥有相同的元素个数,并且对应位置的元素全部相等,则两个vector对象相等;否则不等。
operator<、operator<=、operator>、operator>=:采用字典排序策略比较。
3、vector常见操作:
①vector头文件:
#include ;
using namespace std;//命名空间不可少
②创建vector对象:
vectorvec;//声明int一维数组
vector Vec32;
vector Vec3D;
vector<vector>mVecPoint;//容器的容器, //二维数组
③尾部插入数字:
vec.push_back(a);
Vec32.push_back(cvPoint2D32f(x,y));
Vec3D.push_back(cvPoint3D64f(x,y,z));
mVecPoint.push_back(Vec3D);
void push_back(const T& x):向量尾部增加一个元素X
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元 素x
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n
个相同的元素x
iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭
代器指向元素前插入另一个相同类型向量的[first,last)间的数据
④删除函数
iterator erase(iterator it):删除向量中迭代器指向元素
iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
void pop_back():删除向量中最后一个元素
void clear():清空向量中所有元素
使用下标遍历vector容器:下标从0开始;
FILE *fp=fopen(“2d.txt”,”wt”);
for(inti=0;i<Vec32.size();i++)
{
fsprintf(fp,”%f %f\n”,Vec32[i].x,Vec32[i].y);
}
fclose(fp);
- vector排序:
①在vector中数据类型为基本类型时,可以调用std::sort()实现升序和降序排序;
vector vi ;
vi.push_back(1);
vi.push_back(3);
vi.push_back(0);
sort(vi.begin() , vi.end()); //默认:从小到大
reverse(vi.begin(),vi.end()) //从大到小
降序比较:由大到小
定义排序比较函数:
bool Comp(constint&a,constint&b)
{
return a>b;
}
vi ;
vi.push_back(1);
vi.push_back(3);
vi.push_back(0);
sort(vi.begin() , vi.end()); //默认:从小到大
reverse(vi.begin(),vi.end()) //从大到小
降序比较:由大到小
定义排序比较函数:
bool Comp(constint&a,constint&b)
{
return a>b;
}
调用时:sort(vec.begin(),vec.end(),Comp),这样就降序排序。