1:关联容器和顺序容器
c++中有两种类型的容器:顺序容器和关联容器,顺序容器主要有:vector、list、deque等。其中vector表示一段连续的内存地址,基于数组的实现,list表示非连续的内存,基于链表实现。deque与vector类似,但是对于首元素提供删除和插入的双向支持。关联容器主要有map和set。map是key-value形式的,set是单值。map和set只能存放唯一的key值,multimap和multiset可以存放多个相同的key值。
容器类自动申请和释放内存,我们无需new和delete操作。
2:vector容器的简单介绍
vector 是一个类模板。不是一种数据类型,vector< int>是一种数据类型。Vector的存储空间是连续的,如果要使用vector,需要包含头文件#include< vector>。
vector向量相当于一个数组,vector是最简单的序列式容器,支持随机访问元素,这一属性使得vector有时显得效率低一些。在开发过程中,使用vector作为动态数组的使用是非常方便的。
在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数返回的大小,当超过此分配的空间时再整体重新放分配一块内存存储,这给人以vector可以不指定vector即一个连续内存的大小的感觉。通常此默认的内存分配能完成大部分情况下的存储。
优点:
- 不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组进行动态操作。通常体现在push_back() pop_back()
(2) 随机访问方便,即支持[ ]操作符和 vector.at()
(3) 节省空间。
缺点:
(1) 在内部进行插入删除操作效率低。
(2) 只能在vector的最后进行push和pop,不能在vector的头进行push和pop。
(3) 当动态添加的数据超过vector默认分配的大小时要进行整体的重新分配、拷贝与释放。
3.vector容器的基本使用方法
//1.定义和初始化
vector<int> vec1; //默认初始化,vec1为空
vector<int> vec2(vec1); //使用vec1初始化vec2
vector<int> vec3(vec1.begin(), vec1.end());//使用vec1初始化vec2
vector<int> vec4(10); //10个值为0的元素
vector<int> vec5(10, 4); //10个值为4的元素
//2.常用操作方法
vec1.push_back(100); //尾部添加元素
int size = vec1.size(); //元素个数
bool isEmpty = vec1.empty(); //判断是否为空
cout << vec1[0] << endl; //取得第一个元素
vec1.insert(vec1.end(), 5, 3); //从vec1.back位置插入5个值为3的元素
vec1.pop_back(); //删除末尾元素
vec1.erase(vec1.begin(), vec1.begin() + 2);//删除vec1[0]-vec1[2]之间的元素,不包括vec1[2]其他元素前移
cout << (vec1 == vec2) ? true : false; //判断是否相等==、!=、>=、<=...
vector<int>::iterator iter = vec1.begin(); //获取迭代器首地址
vector<int>::const_iterator c_iter = vec1.begin(); //获取const类型迭代器
vec1.clear(); //清空元素
//3.遍历
//下标法
int length = vec1.size();
for (int i = 0; i<length; i++)
{
cout << vec1[i];
}
cout << endl << endl;
//迭代器法
vector<int>::iterator iter = vec1.begin();
for (; iter != vec1.end(); iter++)
{
cout << *iter;
}
调用find方法(需要include<algorithm>)
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& val)
如查找元素为value,找到则返回迭代器的位置,否则迭代器将指向end()
vector<Type>::iterator iVector;
iVector = std::find(a.begin(), a.end(), value);
if(iVector != a.end())
{
找到了
}
else
{
没找到。
}
4.代码实例
#include <iostream>
#include <vector>
#include <algorithm>
typedef unsigned long U32;
typedef std::vector < U32 > VectorType;
int add(VectorType *pVector ,U32 m)
{
if(NULL == pVector)
{
return -1;
}
pVector->push_back(m); //添加元素到末尾//无返回值
return 0;
}
int remove(VectorType *pVector ,U32 m)
{
if(NULL == pVector)
{
return -1;
}
VectorType::iterator iVector = std::find(pVector->begin(), pVector->end(), m);
if(iVector != pVector->end())
{
pVector->erase(iVector); //参数只能是迭代器
std::cout<<" erase success "<< m<<std::endl;
}
else
{
std::cout<<" not find in pVector"<< m<<std::endl;
}
return 0;
}
int remove_last_one(VectorType *pVector )
{
if(NULL == pVector)
{
std::cout<<"pVector is NULL,(remove_last_one)"<<std::endl;
return -1;
}
if(pVector->empty())
{
std::cout<<"pVector is empty , remove_last_one"<<std::endl;
return -1;
}
pVector->pop_back(); //删除最后一个元素
return 0;
}
int remove_all(VectorType *pVector )
{
if(NULL == pVector)
{
std::cout<<"pVector is NULL,(remove_all)"<<std::endl;
return -1;
}
#if 0
VectorType::iterator iVector = pVector->begin();//;std::find(pVector->begin(), pVector->end(), m);
while(iVector != pVector->end())
{
std::cout<<" remove_all a "<< (*iVector)<<std::endl;
iVector = pVector->erase(iVector);
std::cout<<" remove_all b "<< (*iVector)<<std::endl;
}
#endif //这种做法导致大量的移动操作,但好处是如果元素是指针,我们可以先把内存
//释放了再删除
//erase的返回值是指向删除元素的下一个元素的迭代器指针
#if 1
while(pVector->size() != 0)
{
//pop_back方法无返回值
pVector->pop_back();//删除操作避免大量移动的方法,如果元素有申请堆栈的内存,不可用此方法
}
#endif
#if 0
//以下方法不可行
VectorType::iterator iVector = pVector->end();//;std::find(pVector->begin(), pVector->end(), m);
while(iVector != pVector->begin())
{
std::cout<<" remove_all a "<< (*iVector)<<std::endl;
iVector = pVector->erase(iVector);
std::cout<<" remove_all b "<< (*iVector)<<std::endl;
}
#endif
return 0;
}
void dump(VectorType *pVector)
{
if(NULL == pVector)
{
std::cout<<"pVector is NULL"<<std::endl;
return ;
}
if(pVector->empty()) //判断是否为空
{
std::cout<<"pVector is empty"<<std::endl;
return ;
}
VectorType::iterator iVector = pVector->begin();
while(iVector != pVector->end())
{
std::cout<<" dump "<< (*iVector)<<std::endl;
++iVector;
}
return ;
}
int find(VectorType *pVector ,U32 m,int *pnFlag)
{
if(NULL == pVector || NULL == pnFlag)
{
return -1;
}
*pnFlag = 0;
VectorType::iterator iVector = std::find(pVector->begin(), pVector->end(), m);
if(iVector != pVector->end())
{
std::cout<<" find success "<< m<<std::endl;
*pnFlag = 1;
return 0;
}
else
{
std::cout<<" not find in pVector"<< m<<std::endl;
return -1;
}
}
int insert_one(VectorType *pVector ,U32 val, int iPlace)
{
int i = 0;
if(NULL == pVector || iPlace < 0)
{
std::cout<<"insert_one param error"<<std::endl;
return -1;
}
VectorType::iterator iVector = pVector->begin();
while(iVector != pVector->end())
{
//std::cout<<" dump "<< (*iVector)<<std::endl;
if(i == iPlace)
{
iVector = pVector->insert(iVector , val); //此时insert的返回值是迭代器,插入成功后iVector指向插入的位置
std::cout<<" insert_one after iVector point "<< (*iVector)<<std::endl;
return 0;
}
i++;
++iVector;
}
iVector = pVector->insert(pVector->end() , val);
return 0;
}
int print_size(VectorType *pVector)
{
if(NULL == pVector)
{
std::cout<<"pVector is NULL"<<std::endl;
return -1;
}
if(pVector->empty()) //判断是否为空
{
std::cout<<"pVector is empty (get_size)"<<std::endl;
}
std::cout<<"pVector capacity: "<< pVector->capacity() << " size:"<<pVector->size()<<std::endl;
return 0;
}
int main()
{
VectorType vArray(20);//初始化20个元素的容器
int nFlag =0;
vArray.clear();//把容器的里的元素全部清掉
//添加元素
add(&vArray,5);
add(&vArray,4);
add(&vArray,3);
add(&vArray,2);
add(&vArray,1);
add(&vArray,0);
//插入一个元素 值为6
U32 val = 6;
int place = 2;
insert_one(&vArray, val, place);
//打印capatity size
print_size(&vArray);
dump(&vArray);
//删除末尾元素
remove_last_one(&vArray);
print_size(&vArray);
U32 element = 1;
find(&vArray ,element,&nFlag);
remove(&vArray ,element);
find(&vArray ,element,&nFlag);
element = 8;
//移除元素element
remove(&vArray ,element);
//查找element
find(&vArray ,element,&nFlag);
//移除所有元素
remove_all(&vArray);
dump(&vArray);
print_size(&vArray);
std::vector < U32 >().swap(vArray);//销毁向量的做法
print_size(&vArray);
}