C++ STL
list
list的定义与结构
极少遇到用list的情况
list为双向链表容器,它用节点形式存储元素,并使用指针将节点链接在一起,我们使用时不会用指针,只是list的底层用了指针。
它有双向性(可以在常数时间内进行插入,删除与访问操作),动态大小,不连续存储(同链表)。
可以用迭代器遍历链表中的元素。
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_front(0);
for(int num : mylist){
cout<<num<<" ";
}
但是要时长随机访问的话更推荐vector与deque
stack
stack的定义与结构
栈,是一种后进先出的数据结构,头文件<stack>
只可以包含一个类型,只可以执行元素压到栈顶,或弹出栈顶的操作。
stack的常用函数
push(x)
在栈顶插入元素x
pop()
弹出栈顶元素
top()
返回栈顶元素
empty()
检查栈是否为空
size()
返回栈中元素个数,不可遍历
如果将一个数组依次入栈,再依次取出,可以将数组翻转。
代码示例
stack<int> mystack;
mystack.push(10);
mystack.pop();
set
用的很少
set集合
用于存储一组唯一的元素,不允许重复元素存在,输入重复时会自动忽略,并按一定排序规则进行排序,默认按升序排序(<)。如果为结构体要为结构体重载一个小于号。
底层使用红黑数,插入删除,查找元素的时间复杂度都为对数时间,O(log n)。
insert()
插入元素
erase()
移除元素
find()
查找集合中的元素
lower_bound()
返回第一个不小于给定值的迭代器
upper_bound()
返回第一个大于给定值的迭代器
size()
返回元素数量
empty()
判空
clear()
清空
begin(),end(),rbegin(),rend()
set<int, greater<int> > mySet;
从大到小排了,不传greater为从小到大,4 3 2 1与1 2 3 4
mySet.insert(25);
自定义比较逻辑
struct MyCompare {
bool operator()(const int& a,const int& b) const
{/*自定义比较逻辑*/ return a > b;
}
};
multiset多重集合
可以有重复元素
lower_bound()
与upper_bound()
常与multiset一起用。
对multiset用erase(x)
会将集合中的x全部删除,如果只想删一个就st.erase(st.find(x))
迭代器将第一个遇到的x删除(xxxyz变为xxyz)。
unordered_set无序集合
时间复杂度十分不稳定,用于存储唯一元素,无序,无upper_bound和lower_bound
map
map
是一种关联容器,用于存储一组键值对,其中每一个键都是唯一的。map容器根据键来自动进行排序,并且可以通过键快速查找对应的值。插入,删除,查找的时间复杂度为O(log n)。
inseart(key,value);
插入元素
erase(key);
删除元素(也可能为区间,不过删除区间没有啥意义)
find(key)
查找元素,返回迭代器
count(key)
统计个数,但是map中的key不重复,故只有0与1,常用于判断key是否存在。
size()
返回元素个数,int count = mp.size();
begin返回指向容器起始位置的迭代器end指向末尾的迭代器
clear()
清空
empty()
判空
lower_bound返回第一个不小于指定键的元素位置 如{1,3} {2,5} {3,-1}这时lower_bound(2)返回{2,5}这个位置的迭代器
push_back
multimap
类似map,允许存储多个具有相同键的键值对,实际做题时基本用不到multimap
erase()
删除元素时与multiset一样,直接erase(x)
会将所有都删除,mm.erase(mm.find(x));
count(key)
统计有几个key,在map中只会返回0或1
unordered_map
底层使用哈希函数,快的时候很快慢的时候很慢具有更快的插入删除查找操作,但不保证元素的顺序,不会根据键的顺序进行排序。
他没有lower_bound函数
有极好的平均时间复杂度O(n)与极差的最坏时间复杂度O(n)
代码示例
map<int, string> myMap = {{1,"Apple"}, {2,"Banana"}, {3, "Orange"}};
myMap.insert(make_pair(4, "Grapes"));//传入元素
也可以myMap.insert({4, "Grapes"});
查找myMap[2]
以方括号查找key,返回key对应的值
遍历
for(const auto& pair : myMap) {
cout << "key" << pair.first << ",value" <<pair.second <<endl;
}
删除元素myMap.erase(3)
;或者myMap[3]=0;
判断是否存在
if(myMap.count(3) == 0)cout<<"key 3 not found"<<endl;
multimap的查找与访问元素
auto range = myMultimap.equal_range(2);返回一个左闭右开的表示所有key2的范围的迭代器。
for(auto it = range.first; it != range.second; i++){
cout << "key" << it->first << "value" << it->second <<endl;
}
multimap的删除与清空
myMultimap.erase(2);
把key2都删除。myMultimap.clean()
清空
unordered_map<string, int> myMap = {{"apple", 3}, {"banana", 5}}
用string为key,int为value。也不可以有重复的key.
pair
为模板类,用于表示一对值的组合。位于<utility>头文件中
如pair<int, string> pa(3, "Mike")
;
pair可以将两个值组合,并进行传参,返回等操作。
pair的定义与结构
pair的成员变量可以为结构体类型
pair有两个成员变量first与second
例:
pair<int, double> p1(1, 3.14);
pair<char, string> p2('a', "Hello");
cout<<p1.first<<", "<<p1.second<<endl;
cout<<p2.first<<", "<<p2.second<<endl;
pair的嵌套
pair可以进行嵌套,可以将一个pair对象作为另一个pair对象的成员。
例:
pair<int, int> p1(1, 2);
pair<int, pair<int, int>> p2(3, make_pair(4, 5));
cout<<p2.second.first<<endl;
pair自带排序规则
pair自带规则为按照first成员进行升序排序,若first成员相等,则按照second成员进行升序排序。就是说如果你用sort排序的话会按first成员进行排序,若相等则对second成员进行排序。
例:
vector<pair<int, int>> vec;
vec.push_back(std::make_pair(3, 2));
vec.push_back(std::make_pair(1, 4));
vec.push_back(std::make_pair(2, 1));
sort(vec.begin(), vec.end());
结果为1,4 2,1 3,2
queue
queue队列
queue是一种先进先出的数据结构。好比一根管道。
push(x)
在队尾插入元素x
pop()
弹出队首元素
front()
返回队首元素,常与上一个组合使用
back()
返回队尾元素
empty()
检查队列是否为空
size()
返回队列中元素的个数
priority_queue优先队列
优先队列是按一定的优先级进行排序的,默认按元素的值从大到小进行排序,即最大的元素位于队列的前面。为树形结构
根为top,叶子不用管C++帮我们搞好了。
push(x)
插入O(logN)
pop()
弹出优先队列的顶部元素O(logN)
top()
返回优先队列中的顶部元素O(1)
empty()
判空O(1)
size()
返回队列元素个数O(1)
修改比较函数
仿函数:
struct Compare{
bool operator()(int a,int b){
return a>b;
}
}
int main(){
priority_queue<int,vector<int>, Compare> pq;
}
也可把Compare直接改为greater<int>
(默认为less),将大根堆改为小根堆greater函数对象定义在<functional>头文件中。
如下:
priority_queue<int,vector<int>, greater<int> >;
注意此处一定要加空格">>"写在一起是右移运算符。
平时如果从大到小就不用后面的vector<int>
与greater<int> >;
deque双端队列
允许在两端进行高效插入与删除操作。
push_back(x)
在尾部插入元素x
push_front(x)
在头部插入元素x
pop_back()
弹出尾部元素
pop_front()
front()
返回头部元素
back()
返回尾部元素
empty()
判空
clear()
清空
vector
vector的定义与特性
为动态数组,可以存储一系列相同类型的元素。头文件<vector>
vector<类型> 变量名;
会根据元素数量自动分配内存空间
可以使用索引访问,索引(下标)从0开始,最后一个元素的索引为size() - 1
,但是不可以写成i<=size()-1
,因为size为整数未定型,这样写会变得很大,会出问题,可以强制转换为(int)size()-1
,或者直接写成i<size()
可以用[]
运算符访问。
push_back()
函数在vector末尾添加元素,pop_back()
函数删除末尾元素,可以用insert()
函数在指定位置插入元素,如在1这个位置插入则后面的234向后推,使用erase()
函数删除指定位置元素。
可以使用size()
函数获取vector中元素的数量,使用empty()
函数检查vector是否为空。也可以用resize()
函数调整vector的大小。
vector提供了迭代器.begin()
与.end()
vector的常用函数
push_back();
pop_back();
用pop_back时vector一定不可以为空
迭代器
for(auto it = vec.begin(); it != vec.end; it++){
cout<<*it<<endl;
}
vevctor的排序去重
sort(vec.begin, vec.end());
去重前先[[排序]]
auto last = unique(vec.begin(), vec.end());//将重复的排到后面
vec.erase(last, vec.end());//将后面重复的元素去除
经典代码
vec.erase(unique(vec.begin(), vec.end()), vec.end());//去重
vec.erase(vec.begin() + 4);//将第5个元素删除。
本文作者:Breadcheese
本文链接:https://www.cnblogs.com/breadcheese/p/18001644
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步