STL 即标准模板库(Standard Template Library),是 C++ 标准库的一部分,里面包含了一些模板化的通用的数据结构和算法。由于其模板化的特点,它能够兼容自定义的数据类型,避免大量的造轮子工作。
1. vector
1.1 基本使用
需要添加#include< vector >头文件
#include <iostream>
#include<vector>
using namespace std;
int main() {
// 创建一个vector 可看作动态数组
// 方法1:
vector <int> v;
// vector <int> v(10); 方法2: 直接设定v的大小为10,默认值为0
// vector <int> v(11,2 ); 方法3: 直接设定v的大小为11,默认值为2
// 定义vector大小为10
v.resize(10);
cout << v.size() << endl;
// vector 可用循环i遍历
for (int i = 0; i < 10; i++)
v[i] = i;
// 在容器末尾添加新的元素,“11”
v.push_back(11);
// 也可使用迭代器遍历
// p可看作指针,begin指向容器中第一个元素,end指向容器末尾元素后一位置
for (auto p = v.begin(); p != v.end(); p++)
cout << *p << " ";
return 0;
}
运行结果:

1.2 emplace和emplace_back
也可以使用emplace和emplace_back插入对象,对应insert和push_back
当插入对象为普通类型时,emplace和insert效率相同;当插入对象为类对象时,emplace效率更高,因为它只会调用一次构造函数,但insert会调用构造函数和拷贝构造函数
1.3 迭代器失效
使用迭代器更新vector中的元素后,迭代器可能会失效。每次更新后,需要重新获取迭代器

1.4 扩容机制
当vector中size == captical时,会开辟一个1.5/2倍的新空间,将原有数据拷贝过去,并释放原空间
2. set
2.1 基本操作
set是集合,里面的元素各不相同,会从小到大排序
出现相同元素也只会保留一次(添加头文件)
#include <iostream>
#include<set>
using namespace std;
int main() {
// 定义法1:
set <int> s;
s.insert(3);
s.insert(5);
s.insert(3);
for (auto p = s.begin(); p != s.end(); p++)
cout << *p << " ";
cout << endl;
// 定义2:将s复制到s1
set <int> s1(s);
for (auto p = s1.begin(); p != s1.end(); p++)
cout << *p << " ";
cout << endl;
// 定义3:传入迭代器
set <int> s2(s.begin(), s.end());
for(int p : s2)
cout << p << " ";
cout << endl;
return 0;
}

2.2 set的其他操作
#include <iostream>
#include<set>
using namespace std;
int main() {
// 创建set(不能像vector那样,创建时添加大小和默认值,会报错)
set <int> s;
// 向set中插入元素
s.insert(3);
s.insert(5);
s.insert(1);
// set 不能使用索引遍历,但可以使用迭代器遍历,方法与vector相同
for (auto p = s.begin(); p != s.end(); p++)
cout << *p << " ";
cout << endl;
// 使用find()方法进行值查找,返回值是指针
// 若查到,指针指向查找的值的位置;若未查到,指针指向容器末尾元素后一位置
cout << (s.find(3) != s.end()) << endl; // 判断“3”是否在set中,输出布尔值1/0
cout << (s.find(4) != s.end()) << endl; // 判断“4”是否在set中,输出布尔值1/0
// 删除某个数
s.erase(3);
cout << (s.find(3) != s.end()) << endl; // 判断“3”是否在set中,输出布尔值1/0
}
运行结果:

2.3 set的实现
set底层也是使用红黑树实现的,因此set的增、删、查的复杂度也为O(logn)
3. map
3.1 基本使用
map是键值对,按照键值进行排序,添加头文件< map >
#include <iostream>
#include<map>
#include<string>
using namespace std;
int main() {
// map 是键值对,按键值的ascii码进行排序
// 创建map
map<string, int> m;
// 添加键值对,经排列 h < i < w
m["hello"] = 4;
m["world"] = 2;
m["ihello"] = 3;
// 输出map大小(size()方法容器通用)
cout << "map的长度为:" << m.size() << endl;
// 通过迭代器进行遍历
// 这里的p使用与vector与set有所不同,可看作结构体的指针
for (auto p = m.begin(); p != m.end(); p++)
cout << p->first << ":" << p->second << endl;
cout << endl;
// 使用键值删除元素,erase方法
m.erase("hello");
for (auto p = m.begin(); p != m.end(); p++)
cout << p->first << ":" << p->second << endl;
}
运行结果:

3.2 扩展
map的增,删,查的复杂度都是O(logn),因为底层实现为红黑树

map的类型基于pair<key,value>模板
3.3 upper_bound和lower_bound
upper_bound:返回一个指向第一个大于所给定值的迭代器
lower_bound:返回一个指向第一个不小于所给定值的迭代器

4. 栈
添加< stack > 头文件
#include <iostream>
#include<stack>
using namespace std;
int main() {
// 栈的先进后出特性,只能访问栈顶元素,不能遍历整个栈
// 创建栈
stack <int> s;
// 入栈
s.push(3);
s.push(4);
// 输出栈顶元素
cout << "栈顶元素:" <<s.top() << endl;
s.pop();
cout << "栈顶元素:" << s.top() << endl;
// 输入栈中元素个数(容器通用方法)
cout << "栈中元素个数为:" <<s.size() << endl;
}
运行结果:

5. 队列
添加头文件< queue>
#include <iostream>
#include <queue>
using namespace std;
int main() {
// 创建队列
queue <int> q;
// 入队
for (int i = 1; i <= 10; i++)
q.push(i);
// 队列可以使用front()和back()方法分别访问队首和队尾,队尾入队,队首出队
cout << "队首元素:" << q.front() << endl << "队尾元素:" << q.back() << endl;
// 出队
q.pop();
cout << "队首元素:" << q.front() << endl << "队尾元素:" << q.back() << endl;
// 队列长度
cout << "队列长度为:" << q.size() << endl;
return 0;
}
运行结果:

6. 无序map与set
6.1 基本操作
添加头文件< unordered_map>与< unordered_set>
增删改查的平均时间复杂度为O(1)
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include<string>
using namespace std;
int main() {
// 无序的map与set,不需要进行排序,效率比有序高一些
unordered_map <string, int> m;
unordered_set <int> s;
// 插入等操作与有序的相同
s.insert(3);
s.insert(8);
s.insert(5);
m["hello"] = 2;
m["illo"] = 6;
m["world"] = 4;
// 遍历结果是无规律的
for (auto p = s.begin(); p != s.end(); p++)
cout << *p << " ";
cout << endl;
for (auto p = m.begin(); p != m.end(); p++)
cout << p->first << ":" << p->second << endl;
return 0;
}
运行结果:

6.2 unorder_set存储方式

使用hash将不同元素分到不同的块中,同一块的元素使用链式存储
7. deque

deque的存储不是全部连续的,而是由多个内存块组成。扩容时,不会像vector一样开辟新空间再拷贝,而是新分配一个固定大小的内存块。
8. list
8.1 基本信息
底层为双向链表,不能随机访问

8.2 迭代器失效

迭代器只会在指向的元素被删除时才会失效


1564

被折叠的 条评论
为什么被折叠?



