容器
容器的分类
序列式容器(Sequence containers)
- 每个元素都有固定位置--取决于插入时机和地点和元素值无关
- vector、deque、list、stack、queue
关联式容器(Associated containers)
- 元素位置取决于特定的排序准则,和插入顺序无关
- set、multiset、map、multimap
数据结构 | 描述 | 实现头文件 |
向量(vector) | 连续存储的元素 | <vector> |
列表(list) | 由节点组成的双向链表,每个结点包含着一个元素 | -<list> |
双队列(deque) | 连续存储的指向不同元素的指针所组成的数组 | <deque> |
集合(set) | 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 | <set> |
多重集合(multiset) | 允许存在两个次序相等的元素的集合 | <set> |
栈(stack) | 后进先出的值的排列 | <stack> |
队列(queue) | 先进先出的执的排列 | <queue> |
优先队列(priority_queue) | 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 | <queue> |
映射(map) | 由{键,值}对组成的集合,以某种作用于键对上的谓词排列 | <map> |
多重映射(multimap) | 允许键对有相等的次序的映射 | <map> |
vector容器
vector是将元素置于一个幼态数组中加以管理的容器。
vector可以随机存取元素(支持索引值直接存取,用0操作符或at()方法)
vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时
vector对象的默认构造
vector采用模板类实现,vector对象的默认构造形式
vector对象的带参数构造
- vector(beg,end); //构造函数将[beg,end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
- vector(n,elem); //构造函数将n个elem拷贝给本身。
- vector(const vector &vec);//拷贝构造函数
示例:
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> vecInt;
vector<float> vecFloat;
vector<string> vecString;
int iarr[] = { 1,2,3,4,5 };
vector<int> v1(iarr, iarr + 5);
vector<int> v2(3, 10);//存储3个10
for (int i = 0; i < 3; i++) {
cout << v2[i] << " ";
}
cout << endl;
vector<int> v3(v1);//将v1拷贝到v3里
for (int i = 0; i < 5; i++) {
cout << v3[i] << " ";
}
cout << endl;
}
vector的赋值
- vector.assign(beg,end); //将[beg,end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间
- vector.assign(n,elem); //将n个elem拷四赋值给本身。
- vector& operator=(const vector &vec); //重载等号操作符
- vectorswap(vec); //将vec与本身的元素互换。
示例:
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> vecIntA(10,10);
vector<int> vecIntB, vecIntC, vecIntD;
//vector.assign(beg,end)
int iArray[] = { 0,1,2,3,4 };
vecIntA.assign(iArray, iArray + 5);
for (int i = 0; i < 5; i++) {
cout << vecIntA[i] << " ";
}
cout << endl;
cout << vecIntA.size() << endl;
//assign是覆盖而并不是简单的赋值
vecIntB.assign(vecIntA.begin(), vecIntA.end());
/*vecIntB = { 1,2,3,4 };
cout << vecIntB.size() << endl;*/
for (int i = 0; i < 5; i++) {
cout << vecIntB[i] << " ";
}
cout << endl;
//- vector.assign(n,elem); //将n个elem拷四赋值给本身。
vecIntC.assign(4, 10);
for (int i = 0; i < 4; i++) {
cout << vecIntC[i] << " ";
}
cout << endl;
//vectorswap(vec); //将vec与本身的元素互换
vecIntB.swap(vecIntC);
for (int i = 0; i < vecIntB.size(); i++) {
cout << vecIntB[i] << " ";
}
cout << endl;
for (int i = 0; i < vecIntC.size(); i++) {
cout << vecIntC[i] << " ";
}
cout << endl;
//vector& operator=(const vector &vec);
vecIntD = { 1,1,1,1,1,1 };
vecIntD = vecIntC;
for (int i = 0; i < vecIntD.size(); i++) {
cout << vecIntD[i] << " ";
}
cout << endl;
}
vector的大小
- vector.size(); //返回容器中元素的个数
- vector.empty0;//判断容器是否为空
- vector.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短则末尾超出容器长度的元素被删除。
- vector.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
示例:
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> v1;
cout << "v1.size=" << v1.size() << endl;
if (v1.empty()) {
cout << "v1 is empty" << endl;
}
int iArray[] = { 0,1,2,3,4 };
v1.assign(iArray, iArray + 5);
v1.resize(3);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
cout << "v1.size=" << v1.size() << endl;
v1.resize(7);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
cout << "v1.size=" << v1.size() << endl;
//将容器的长度变长,并且扩展出来的新的元素赋值为指定的值
v1.resize(10, 100);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
cout << "v1.size=" << v1.size() << endl;
}
vector的访问方式
- vec.at(idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_rdnge异常。
- vec[idx]; //返回索引idx所指的数据,越界时,运行直接报错
示例:
#include<iostream>
#include<vector>
using namespace std;
int main() {
int a[] = { 1,2,3,4 };
vector<int> v1(a, a + 4);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
v1.at(8) = 100;
}
注:用下标法访问可以正常读写,但使用at()会报错,并终止程序,用下表法访问的时候不要下标越界,否则会访问不属于vector容器所定义的空间,造成不必要的数据错误修改
当code后面的数不是0时,代表有异常报错
Vector的插入
理论知识
- vector.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置,
- vectorinsert(pos,n,elem); //在pos位置插入n个elem数据,无返回值,
- vector.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值
vector末尾的添加移除操作
- vector <int> veclnt;
- vecint.push_back(); //在容器尾部加入一个元素.
- vecint.pop_back();//删除容器末尾元素
示例:
#include<iostream>
#include<vector>
using namespace std;
int main() {
int a[] = { 1,2,3,4 };
vector<int> v1(a, a + 4);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//从末尾插入一个元素
v1.push_back(10);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//删除末尾元素
v1.pop_back();
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//插入元素
v1.insert(v1.begin() + 3, 100);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//在指定的位置插入多个元素
v1.insert(v1.begin() + 3,3, 100);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//在指定的位置插入多个元素
v1.insert(v1.begin() + 3, a, a+4);
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
}