== 关于C++|STL == 学习笔记
放假期间懒了好多 更一下博客 当作学习笔记 也希望方便有需求的小伙伴学习
个人风格喜欢通俗易懂的 所以可能不会用一些复杂的术语来写 希望能够看懂
啊哈 如果有错误欢迎指正
上一篇介绍了 vector 和 set
接下来介绍 map stack queue
映射 map
简介
map 内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的
map 是一个关联容器 自动建立Key - value的对应。key 和 value可以是任意需要的类型 可以通过key 来快速查找 修改 或者删除
map的兄弟 unordered_map
C++ STL中的unordered_map可类比于Python中的字典。其实现使用了哈希表,可以以O(1)的时间复杂度访问到对应元素,但缺点是有较高的额外空间复杂度。与之对应,STL中的map对应的数据结构是红黑树,红黑树内的数据时有序的,在红黑树上查找的时间复杂度是O(logN),相对于unordered_map的查询速度有所下降,但额外空间开销减小。
1 头文件
#include<map>
2 定义类型与构造
map 可以定义各种基本数据类型 也包括结构体等
定义形式为`
map<key,value>mp;
//例如;
map<int,string>mp;
mp[1]="abc";
mp[2]="bcd";
3 主要函数
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
4 主要操作
- 插入遍历元素
插入添加元素时通常有两种方法 一种是直接定义添加 一种是借用pair进行添加
下面先简单描述一下通过pair的方法
pair是一个结构体,有first和second 两个域,可以直接访问
而make_pair是返回一个pair <类型,类型> 的数 如make_pair(“abc”,123); 但还要找个pair <string,int>类型的变量来接受返回值。
例如:
map<string,int>mp;
mp.insert(pair<string,int>("abc",3));
mp.insert(make_pair<string,int>("bcd",4));
也可以直接定义
如:
mp["mno"]=5;
关于遍历
#include <iostream>
#include <map>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
map<string,int>mp;
map<string,int>::iterator it;
mp.insert(pair<string,int>("abc",3));
mp.insert(pair<string,int>("bcd",4));
mp["a"]=5;
for(it = mp.begin(); it!= mp.end(); it++)
cout<<(*it).first<<','<<(*it).second<<endl;
//输出结果为 a,5 abc,3 bcd,4
//从输出结果来看 map中会按key值按字典序排序
mp["a"]=7;//修改值
for(it = mp.begin(); it!= mp.end(); it++)
cout<<(*it).first<<','<<(*it).second<<endl;
//输出结果为 a,7 abc,3 bcd,4
}
- 查找删除元素
#include <iostream>
#include <map>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
map<string,int>mp;
map<string,int>::iterator it;
mp.insert(pair<string,int>("abc",3));
mp.insert(pair<string,int>("bcd",4));
mp["a"]=5;
mp["b"]=1;
mp["c"]=6;
for(it = mp.begin(); it!= mp.end(); it++)
cout<<(*it).first<<','<<(*it).second<<endl;
//输出结果为 a,5 abc,3 b,1 bcd,4 c,6
cout<<mp.count("a")<<endl;
//count 函数 可以判断关键字是否出现 输出结果为 1
cout<<mp.count("m")<<endl;//输出结果为 0
mp.erase("a");//直接用键值 进行输出
it = mp.find("b");
//find函数可以查找值 找到返回迭代器位置 搜索不到返回end位置
mp.erase(mp.begin(),it);//通过迭代器删除一个区间的值
for(it = mp.begin(); it!= mp.end(); it++)
cout<<(*it).first<<','<<(*it).second<<endl;
//输出结果为 b,1 bcd,4 c,6
}
- 关于排序
非结构体类型
#include <iostream>
#include <map>
#include<cstring>
#include<algorithm>
using namespace std;
struct mycmp
{
//自定义完成 从大到小排序
bool operator() (const int &a, const int &b)
{return a > b;}
};
int main()
{
map<int, string, mycmp> mp;
mp[10] = "abc";
mp[5] = "bdc";
mp[25] = "nk";
mp[15] = "op";
map<int, string, mycmp>::iterator it;
for(it = mp.begin(); it != mp.end(); it++)
cout<<(*it).first<<','<<(*it).second<<endl;
//输出结果为 25,nk 15,op 10,abc 5,bdc
}
结构体类型
#include <iostream>
#include <map>
#include<cstring>
#include<algorithm>
using namespace std;
struct stu
{
int id;
string name;
//重载小于号 进行结构体排序
bool operator <(stu const &a) const
{
if(id!=a.id) return id < a.id;
else return name < a.name;
}
};
int main()
{
map<stu,int>mp;
stu s[5];
s[0].id = 234;s[0].name="abc";
s[1].id = 123;s[1].name="bcd";
s[2].id = 123;s[2].name="mno";
s[3].id = 234;s[3].name="acd";
s[4].id = 456;s[4].name="xnd";
for(int i=0;i<5;i++)
mp.insert(make_pair(s[i],i+1));
map<stu,int>::iterator it;
for(it =mp.begin();it!=mp.end();it++)
cout<<it->first.id<<','<<it->first.name<<' '<<it->second<<endl;
}
程序运行结果图
栈 stack 和 队列 queue
1 定义与头文件
栈:栈(stack)又名堆栈,它是限定在表的一端进行插入和删除操作的线性表(后进先出)。这一端被称为栈顶,相对地,把另一端称为栈底。不含元素的空表称为空栈。
队列:和栈相反,队列(queue)是一种先进先出的线性表。它只允许在表的前端进行删除操作,而在表的后端进行插入操作。允许插入的一端称为队尾(rear),允许删除的一端称为队头(front)
向一个栈插入新元素又称作入栈,从一个栈删除元素又称作出栈。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队
和线性表一样,栈和队列的存储结构也包括顺序和链式两种
stack :
头文件
#include<stack>
定义方法
stack <数据类型> 数据名 如:stack < int > a
queue:
头文件
#include<queue>
定义方法
queue <数据类型> 数据名 如:queue < int > q
2 基本操作函数
2.1 stack
a.push(); //向栈内压入一个成员
a.pop(); //从栈顶弹出一个成员
a.empty(); //为空返回true,否则返回false
a.top(); //返回栈顶,但不删除成员
a.size(); //返回栈的大小
2.2 queue
q.push(); //在队尾插入数据
q.pop(); //在队首删除数据
q.empty(); //为空返回true,否则返回false
q.front(); //返回队首元素
q.back(); //返回队尾的元素
q.size(); //返回队列的大小
3 关于数组 和 链式 栈 跟 队列
引一波大佬的文章
其实就是我自己懒得总结了 (bushi
基本上主要用到的就是这些啦
好好掌握并通过实际运用可以更好的掌握理解
让它成为一个好用的工具