数据的存储访问比较方便,可以像数组一阿姨那个使用[index]访问或修改值,适用于对元素修改和查看比较多的情况,对于insert或erase比较多的操作,很影响效率,不建议使用vector
#include
using namespace std;//需要打开std命名空间
vector vec;//空的向量
vector vec2(2);//构建了容量和使用量,并使用默认的初始化值,这里容量和使用量都是2
vector vec3(2,3);//构建了容量和使用量,并指定了初始化值,这里容量和使用量都是2,初始值为3
vector vec4{ 1,2,3,4 };//使用初始化列表,进行构建 这里容量和使用量都是4
int arr[5] = { 5,6,7,8,9 };//通过连续的空间(比如数组)进行构建向量
vector vec5(arr, arr + 3);//左闭右开
cout << vec2.capacity() << " " << vec2.size() << endl;//输出容量 使用量
vector::iterator ite = vec4.begin();
while (ite != vec4.end()) {
cout << *ite << " ";
ite++;
}
cout << endl;
for (int v : vec5) cout << v << " ";
vec5.push_back(7);//尾添加
vec5.pop_back();//尾删除
ite = vec5.begin();
vec5.insert(ite, 4);//在指向位置之前添加
ite += 2;//此迭代器支持+=
ite=vec5.erase(ite);//删除时,迭代器会失效,可以接一下返回值,返回的是删除的下一个的迭代器
vec.clear();// //使用量为0,容量不变,相当于是把矿泉水倒没了,瓶子还在
vec.resize(3);//重新设定使用量,如果新设定的使用量小于容量,那么容量不会受影响,如果超过了容量,会导致扩容
vec.swap(vec2);
//可以用此方法来清空向量(容量和使用量均为0)
vector().swap(vec);//这里是把已存在的向量和创建的临时变量(使用量和容量均为0)进行交换
vec3.shrink_to_fit();
1.vector是连续性空间,顺序存储,list链式结构体,链式存储
2.vector在非尾部插入,删除节点会导致其他元素的拷贝移动,list则不会影响其他节点元素
3.vector一次性分配好内存,使用量不够时,申请内存重新分配。list每次插入新节点时都会申请内存
4.vector随机访问性能好,插入删除性能差;list随机访问性能差,插入删除性能好
5.vector具有容量和使用量的概念,而list只有使用量(即长度)概念
deque是一种双向开口的连续性空间,可以在头尾两端分别做元素的插入和删除操作-
#include
using namespace std;//需要打开std命名空间
deque de{ 1,2,3,4 };//使用初始化列表
de.push_front(0);//头添加
de.push_back(5);//尾添加
cout << de.size() << endl;//输出长度
deque::iterator ite = de.begin();
while (ite != de.end()) {
cout << *ite << " ";
ite+=1;
}
for (int v : de) {
cout << v << " ";
}
for (int i = 0; i < de.size(); i += 1) {
cout << de[i] << " ";//通过下标访问元素
}
所有元素都会根据元素的键值自动排序,map的所有元素都是pair,同时拥有键值和实值。不允许两个元素拥有相同的键值,map的键值关系到map元素的排列规则,任意改变map元素键值将严重破环map的组织,所以不可以通过map的迭代器来改变map的键值,但是可以通过迭代器来改变元素的实值
查找效率:O(log2(n)),内部实现红黑树
#include
map m1{ {'r',1},{'q',2}};//使用初始化列表
m1['a'] = 3;//[]里是键值,=右边的是实值
map::iterator ite = m1.begin();
while (ite != m1.end()) {
cout << ite->first << "-" << ite->second << endl;
ite++;
}
for (pair v : m1) {
cout << v.first << "-" << v.second<<" ";
}
m1.insert(pair('b', 4));
//如果键值存在,则插入失败,可通过bool判断,返回的迭代器指向的是原有键值的元素
//此函数的返回值为pair<迭代器,bool>,我们接一下,看一下它的bool返回值
pair
ite = m1.begin();
ite = m1.erase(ite);//可以用迭代器接一下返回值,防止迭代器失效
ite = m1.find('r');//通过键值找,没找到返回的是无效的那个元素( m1.end() )
ite = m1.upper_bound('c');//返回大于该键值的map的迭代器
ite = m1.lower_bound('c');//返回大于等于该键值的map的迭代器
//可以根据这种方法判断键值是否存在
char c = 'i';
if (m1.upper_bound(c) != m1.lower_bound(c)) {
cout << "键值存在" << endl;
}
else {
cout << "键值不存在" << endl;
}
所有元素都会根据元素的键值自动排序,set的元素不像map那样可以同时拥有键值和实值,set元素的键值就是实值,实值就是键值,不允许两个元素拥有相同的键值,因为set的元素值就是其键值,关系到set元素的排列规则,任意改变set元素值将严重破环set的组织
查找效率O(log2(n)),内部实现红黑树
#include
using namespace std;//需要打开std命名空间
set st{4,2,6,0};//使用初始化列表
set ::iterator ite = st.begin();
while (ite != st.end()) {
cout << *ite<< endl;
ite++;
}
for (int v : m1) {
cout << v <<" ";
}
st.insert(4);
//如果键值存在,则插入失败,可通过bool判断,返回的迭代器指向的是原有键值的元素
ite = st.begin();
ite = st.erase(ite);//可以用迭代器接一下返回值,防止迭代器失效
基于hashTable(哈希表),数据的存储和查找效率非常高,几乎可以看作常量时间,相应的代价是消耗更多的内存,使用一个较大的数组来存储空间,经过计算,使得每个元素与数组下标有唯一的对应关系,查找时直接定位
查找效率O(1)
无序
#include
using namespace std;//需要打开std命名空间
unorder_map m1{ {'r',1},{'q',2}};//使用初始化列表
m1['a'] = 3;//[]里是键值,=右边的是实值
unorder_map::iterator ite = m1.begin();
while (ite != m1.end()) {
cout << ite->first << "-" << ite->second << endl;
ite++;
}
for (pair v : m1) {
cout << v.first << "-" << v.second<<" ";
}
m1.insert(pair('b', 4));
//如果键值存在,则插入失败,可通过bool判断,返回的迭代器指向的是原有键值的元素
ite = m1.begin();
ite = m1.erase(ite);//可以用迭代器接一下返回值,防止迭代器失效
ite = m1.find('r');//通过键值找,没找到返回的是无效的那个元素( m1.end() )