STL由六大部分组成
1.容器:各种数据结构,顺序表、链表、队列、红黑树、哈希表等
2.迭代器(Iterator):用于访问容器中成员的方式,本质是元素的位置(本质是指针)
每一个容器都有自己的迭代器,一般分为两种:const 和 非const
3.适配器(Adapter):在容器的基本之上,封装统一的接口(函数)
4.仿函数(Function):用于容器的操作算法的方式(条件,回传元素等)
5.算法(Algorithm):各类容器的操作函数
6.配置器(Allocator):用于管理容器的大小,每个容器都有自己的配置器(内存分配器)
容器分类
通用容器:
vector:动态数组,连续内存,尾插快、中间删改慢,支持随机访问
deque:双端队列,分段连续内存,头尾增删都快,支持随机访问
list:双向循环链表,不连续内存,任意位置增删快,不支持随机访问
有序关联容器:
pair:键值对模板 pair<Key, Value>,只是结构体,不算正式容器,用来存一组键值
map:key 唯一、自动升序,键不重复
multimap:key 可以重复、自动升序
set:只存 key、元素唯一、自动升序
multiset:只存 key、元素允许重复、自动升序
Json:js的只含有属性对象的字符串化。
两种格式:1.{"键名":值,"键名":值2,...}
2.json数组【值,...】
值的类型:字符串,数值,小数,数组,对象
无序关联容器:
unordered_map:无序,key 唯一
unordered_multimap:无序,key 可重复
unordered_set:无序,元素唯一
unordered_multiset:无序,元素可重复
容器适配器:
stack 栈:后进先出,默认底层 deque
queue 队列:先进先出,默认底层 deque priority_queue
优先队列:堆结构,自动排序,默认底层 vector
vector容器(数组)
创建容器
vector<int>ids;
vector<int>ids({2,5,8,1,0,4});//初始化列表
vector<int>ids2(ids.begin()+3,ids.end());
int arr[3]{ 9,10,2 };
vector<int>ns(arr, arr + 3);//将数组转成vector
vector的迭代器遍历元素
vector<int>::iterator it = ids.begin();//非const迭代器
while (it != ids.end()) {
//修改当前it位置上的元素内容
*it += 10;
cout << *it << " ";
it++;//vector的迭代器可以自增自减
}
cout << endl;
下标访问方式 迭代元素
for (int i = 0; i < ids2.size(); i++) {
cout << ids2[i] << " ";
}
cout << endl;
vector新增元素
1.尾部追加
ids2.push_back(100);
2.头部插入
ids2.emplace(ids2.begin(),99);
ids2.insert(ids2.begin(), 88);
3.中间插入
auto cit = ids2.begin() + ids2.size() / 2;
ids2.emplace(cit,66);
vector删除元素
1.清空
ids2.clear();
2.删除头元素
ids2.erase(ids2.begin());
3.删除尾部元素
ids2.pop_back();
调整大小,删除多余空间
ids2.reserve(ids2.size());//调整大小
ids2.shrink_to_fit();//删除多余空间
vector扩容
vector每次扩容的倍数是:1.5倍
每次扩容都要创建新空间,复制旧空间中的元素到新空间,释放旧空间。
为了避免扩容,可以提前预备空间
a.reserve(100);//提前预备100个空间
deque双端队列
插入
头部插入
q1.push_front(10);
尾部插入
q1.push_back(5);
删除
尾弹出
q1.pop_back();
头弹出
q1.pop_front();
清空
q1.clear();
cpp
//删除 3 元素
deque<int>::iterator delIt;
it = q1.begin();
while (it != q1.end()) {
if (*it == 3) {
delIt = it;
break;
}
it++;
}
if (delIt != q1.end()) {//验证删除元素的位置是否找到
q1.erase(delIt);//当删除一个元素之后,之前获取的迭代器可能无效
}
//重新获取迭代器
it = q1.begin();
while (it != q1.end()) {
cout << *it << " ";
it++;
}
cout << endl;
插入
insert();
第一个元素的值
q1.front()
最后一个元素的值
q1.back()
从右边开始
q1.rbegin();
从右边结束
q1.rend();
list(列表)基于链表实现
插入
头部插入
v12.push_front(10);
尾部插入
v12.push_back(5);
删除
尾弹出
v12.pop_back();
头弹出
v12.pop_front();
清空
v12.clear();
直接删除元素
v12.remove(10);//所有的10都删除
pair键值对
Key Value
创建
方式一:
pair<int, string>name1;
//访问键
name1.first = 1001;
//访问值
name1.second = "disen";
方式二:
pair<int, string>name2({ 1002,"Lucy" });
方式三:
pair<int, string>name3 = make_pair(1003, "Mack");
打印:
cout << name1.first << ":" << name1.second << endl;
map哈希
内部实现
红黑树(有序set也是)
map创建多个pair键值对
map<int, string>names({ name1,name2,name3 });
新增
names.emplace(make_pair(1004, "xiaoli"));
names.insert(make_pair(1005, "Cerry"));
names.insert({ {1006,"daA"},{1007,"xiaoB"} });
//names.emplace({ 1009,"xiaoC" });//报错,不支持初始化列表
删除元素pair
names.erase(1001);//按键
names.erase(names.begin());//位置
auto ret_it = names.find(1001);
cout << "1001是否存在:" << (ret_it != names.end()) << endl;
清空
names.clear();
cout << "names size is:" << names.size() << ",is empty:" << names.empty() << endl;
修改指定键的Value
names[1001] = "Jack";
cout << names[1001] << endl;
查询
auto ret_it = names.find(1001);
cout << "1001是否存在:" << (ret_it != names.end()) << endl;
迭代所有的元素(pair)
auto it = names.begin();
while (it != names.end()) {
//it代表某一个pair<int,string>的地址
cout << it->first << ":" << it->second << endl;
it++;//it+=1是错误的,只能自增自减。
}
cout << endl;
实现从大到小排序
//创建map时,第三个泛型指定Key比较的仿函数类
map<int, string,greater<int>>names({ name1,name2,name3 });
多键map
multimap <int, string>m1({
{1,"A"},
{3,"B"},
{2,"C"},
{1,"D"},
{2,"E"},
{3,"F"}
});
删除键时,是所有的都删除吗?
是,是1的都删除
set/multist容器
multist容器:元素只有键(Key),默认元素从小到大排序,结构也是红黑树。
set:有序,不重复(可用于去重),结构是红黑树。
新增数据
s1.emplace(0);
cout << "first item:" << *it << endl;
删除数据
s1.erase(1);//新增或删除时,原有的迭代器可能会失效,需要重新获取
cout << "first item:" << *it << endl;
统计
cout << "set for 5:" << s1.count(5)<<endl;//统计有没有5
仿函数
是一个类,类中重写了operator()运算符函数