C++:vector容器大全
1、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)的尾部

2、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。

3、vector构造函数原型:
template<typename T>
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<string> v1; // 创建空容器,其对象类型为string类
vector<string> v2(10); // 创建有10个具有初始值(即空串)的string类对象的 容器
vector<string> v3(5, "hello"); // 创建有5个值为“hello”的string类对象的容 器
vector<string> v4(v3.begin(), v3.end()); // v4是与v3相同的容器(完全复制)

4、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的值补全。
reference front();//返回容器中第一个元素的引用(容器必须非空)
reference back(); // 返回容器中最后一个元素的引用(容器必须非空)
reference operator[](size_typepos); // 返回下标为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();

5、vector对象的比较:(非成员函数)
有六个比较运算符:
operator==、
operator!=、
operator<、
operator<=、
operator>、
operator>=。
其中,
operator==和operator!=:如果vector对象拥有相同的元素个数,并且对应位置的元素全部相等,则两个vector对象相等;否则不等。
operator<、operator<=、operator>、operator>=:采用字典排序策略比较。
6、vector常见操作:
①vector头文件:
#include <vector>;
using namespace std;//命名空间不可少
②创建vector对象:
vector<int>vec;//声明int一维数组
vector<CvPoint2D32f> Vec32;
vector<CvPoint3D64f> Vec3D;
vector<vector<CvPoint3D64f>>mVecPoint;//容器的容器, //二维数组
③尾部插入数字:
vec.push_back(a);
Vec32.push_back(cvPoint2D32f(x,y));
Vec3D.push_back(cvPoint3D64f(x,y,z));
mVecPoint.push_back(Vec3D);
④使用下标遍历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);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
【注】:遍历容器的容器,遍历二维数组:
for (int i=0;i<mVecPoint.size();i++)//先遍历大容器
{
for(int j=0;j<mVecPoint [i].size();j++)//再遍历小容器
{
cout<<mVecPoint[i][j].x<<mVecPoint[i][j].y<<mVecPoint[i][j].z<<endl;
}
}
定义一个二维的动态数组:
vector< vector<int>> Array( 10, vector<int>(0) );
for( j = 0; j < 10; j++ )
{
for ( i = 0; i< 9; i++ )
{
Array[ j ].push_back( i );
}
}
for( j = 0; j < 10; j++ )
{
for(i = 0; i< Array[ j ].size(); i++ )
{
cout<< Array[ j ][ i ] << " ";
}
cout<<endl;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
⑤使用迭代器访问元素:
vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;
⑥插入元素:
vec.insert(vec.begin()+i,a);//在第i+1个元素前面插入a,a就变成第i+1个元素了
⑦删除元素:
vec.erase(vec.begin()+2);删除第三个元素

7、vector中元素数据类型可以为:
int、double、string、
CvPoint2D32f、CvPoint2D64f、vector、结构体等;
容器中装入自定义的数据类型:
// 自定义一个class
class Cmyclass
{
};
// 定义一个存放class的容器
vector<Cmyclass>MyVec;
vector中存放结构体类型时,常见两种方法:
方法一:放入结构体类型变量的副本;
方法二:放入指向结构体类型变量的指针;
假设结构体类型变量如下:
typedef struct student
{
char school_name[100];
char gender;//性别
int age;
bool is_absent;
}StudentInfo;
示例:
示例:如下图





8、vector排序:
①在vector中数据类型为基本类型时,可以调用std::sort()实现升序和降序排序;
vector<int> 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),这样就降序排序。
9、②而当vector的数据类型为自定义结构体类型时,怎样实现升序与降序排列呢?
有两种方法:
方法1:修改结构体或类的定义部分,sort函数实现
方法2 :类或结构体外定义函数,使用sort调用函数来实现:
如图所示:




