Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >⭐️STL⭐️之list,set,map全解,❤️算法必备❤️<下>

⭐️STL⭐️之list,set,map全解,❤️算法必备❤️<下>

作者头像
秋名山码神
发布于 2022-12-13 06:16:55
发布于 2022-12-13 06:16:55
30900
代码可运行
举报
文章被收录于专栏:码神随笔码神随笔
运行总次数:0
代码可运行

文章目录

😘 闲聊几句

时间过的很快,码神马上就要开学了,这也是STL系列的最后一篇了,假期学了不少,距离自己的奥赛巅峰水平可以说是十分接近了,如果说学这c++有什么用的话,可能就是兴趣所至吧,在博客更新之际,也认识了不少行业大佬,给我提了不少意见,感谢!STL完了以后,就是算法和python脚本吧,做自己想做的事情,更要做难的事情,总体来说STL的浏览量不多,但是还要说,why?因为有些算法题,你适当的使用STL,用过的都知道👍,所以我还是坚持将STL讲完了、 那就这么多,开始吧:

  1. list ——链表
  2. set ——关联式容器,底层是由二叉树实现的
  3. map容器

👍 list

对数据结构中链表陌生的兄弟们,可以看下我的码神爆肝5w字数据结构,记得我说过一句话,数组的缺点就是链表的优点,链表的缺点就是链表的优点,还记得数组的优点是什么?数组的优点是:可以随机访问,缺点是:插入和删除要移动所有元素,同样可以类比出链表的优缺点。 STL中的链表略有不同,是STL中链表是双向链表

和vector的操作基本一致,比较不同的是在删除操作时多了个remove(c):删除与c一样的数据,开车了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<list>
using namespace std;
void print(list<int> &l)
{
	for (list<int> ::iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it<<" ";
	}
	cout << endl;
}
void test01()
{
	list<int> l;
	l.push_back(10);
	l.push_back(20);
	l.push_front(100);
	l.push_front(200);
	if (l.empty())
	{
		cout << "为空";
	}
	else
	{
		cout<<l.size()<<endl;
	}
	print(l);
	//200 100 10 20
	l.pop_back();
	print(l);
	//200 100 10
	l.clear();
}
int main()
{
	test01();
	return 0;
}

这里对比,vector值得注意的是list是链式存储,所以在迭代器iterator中出现,it+1,等操作,取而代之的是it++,一个一个走 用专业方式就是说,支持it+1,是支持随机访问,反之就是不支持随机访问不能用at和【】

👍list的反转和排序

这个我感觉还是有点用的,所以单独说一下, 先来说反转:reverse函数 排序:有个algorithm中的sort不知道还记得不?但是有个前提是,sort只适用在随机访问的数据结构中,list为了方便引入了专门的sort,使用方法是l.sort(), 下面我们用代码来实现一下,这俩个功能

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<algorithm>
#include<list>
using namespace std;
void print(list<int> &L)//打印
{
	for (list<int> ::iterator it = L.begin(); it != L.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
bool fanzhuan(int v1,int v2)
{
	return v1 > v2;
}
void test01()
{
	list<int> l1;
	l1.push_back(10);
	l1.push_back(20);
	l1.push_back(30);
	l1.push_back(20);
	l1.push_back(10);
	print(l1);
	l1.reverse();
	print(l1);
	//从小到大排
	l1.sort();
	print(l1);
	//从大到小
	l1.reverse();
	print(l1);
	//换一个方式
	l1.push_front(10);
	l1.sort(fanzhuan);
	print(l1);
	
}
int main()
{
	test01();
	return 0;
}

可以看到我在实现从大到小时,使用了俩个方法,我们为什么不直接反转呢?原因还是从效率上考虑的,首先我们要明白反转的本质是: 初始化一个为 null 的 previous node(prev),然后遍历链表的同时,当前 node (curr)的下一个(next)指向前一个 node(prev), 在改变当前 node 的指向之前,用一个临时变量记录当前 node 的下一个 node. 即

可以看出时间效率有点低,所以用bool变量写了个函数,来实现从小到大的排序。

👍set/multiset

所有元素都会在插入时自动被排序这应该是它最主要的特定了! 这两个是属于关联式容器,其底层架构是由二叉树实现的,那么如果没有区别,肯定是不行的,要不然直接用一个不就好了嘛,看区别:

  • set不允许有重复元素
  • multiset允许有重复元素

看一下set的基本操作:

  • empty
  • size
  • swap——交换俩个集合
  • insert——插入
  • erase——删除
  • 清空:erase(s.benin(),s.end())
  • clear()
  • find—查找
  • 存在返回s的迭代器,不存在返回s.end()
  • count(key)——统计key的个数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//set是一个容器,区别是当他刚插入是就已经排好了,集合
#include<set>
#include<iostream>
using namespace std;
void print(set<int> &s)
{
	for (set<int> ::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(5);
	s1.insert(1);
	set<int>s2;
	s2.insert(44);
	s2.insert(11);
	s2.insert(55);
	print(s2);
	print(s1);
	//交换
	s1.swap(s2);
	print(s2);
	print(s1);
	cout<<s1.cout(11);
	//应该是1,因为s1和s2互换了序列
	int num=s1.count(10);
	cout<<num<<endl;
	应该为0
	cout << s1.size() << " " << s2.size();

}
int main()
{
	test01();
	return 0;
}

multiset,下来我们来验证一下,前面说过这个容器允许重复插入,这个头文件仍然使用set

下面我们用仿函数来改变set的排序,让它从大到小来进行排序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
//仿函数
class compare
{
public:
	bool operator()(int l1,int l2)
	{
		return l1 > l2;
	}
};
void print(set<int> &s)
{
	for (set<int> ::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	set<int> s;
	s.insert(30);
	s.insert(20);
	s.insert(40);
	s.insert(50);
	s.insert(10);
	print(s);
	//排序
	set<int, compare>s1;
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);
	s1.insert(50);
	s1.insert(10);
	//print(s1);
	for (set<int, compare>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << " ";
	}
}
int main()
{
	test01();
	return 0;
}

👍对组

听名字来看,应该是成对出现的,所以叫对组,比较简单

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<string>
using namespace std;
void test01()
{
	pair<string, int> p(string("masheng"), 20);
	cout << p.first << " " << p.second << endl;
	pair<string, int>p1("tom", 18);
	cout << p1.first << " " << p1.second << endl;

}
int main()
{
	test01();
	return 0;
}

这里我们运用到了pair关键字,对

👍map / multimap

也是使用频率比较高的容器,由于它的性能高,效率高,其底层是由红黑树实现的,但是如果展开来讲红黑树的话,太长了,所以我们,直接来看这个容器,值得注意的一点是:这个容器的每一个元素都是pair,上会讲到的对组,其中对组的第一个元素为key(键值),后一个元素为value(实值)。 这俩个容器的区别有点像set map中不允许有重复的key值元素 multimap允许有重复的key值元素 都有的特点有:

  • 所有的元素都自动排列
  • 可以根据key值快速找到value值
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<map>
#include<iostream>
using namespace std;
void print(map<int,int> &m1)
{
	for (map<int,int> ::iterator it=m1.begin();it!=m1.end();it++)
	{
		cout << it->first << " " << it->second;
	}
	cout << endl;
}
void test01()
{
	map<int, int> m;
	//用pair传入
	m.insert(pair<int, int>(1, 5));
	m.insert(pair<int, int>(8, 5));
	m.insert(pair<int, int>(3, 5));
	//可以看出根据key值来排序
	map<int, int>m1(m);
	m1 = m;
	print(m);
}
int main()
{
	test01();
	return 0;
}

和其他容器一样,我们看几个函数

  • size——大小
  • empty——是否为空
  • swap——交换集合
  • insert——之前用到过的插入
  • clear——清空
  • erase——删除
  • find——查找到了返回迭代器,查找不到返回end
  • count——通上也是统计

值得注意的是map的用【】插入,查找的功能 在用【】查找时,如果查找的数据没有,那么编译器会自动赋值一个数据给到map容器,插入时,value值为0,key值为所查找的值 m[5]=10;,假如5没有,那么5对应的value就为10,或者是这样m【5】;这样5对应0 还有插入:m.insert(make_pair(5,20))和上面的m.insert(<int,int>5,20) 都是比较常用的,但是我不建议在插入时使用【】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void test01()
{
	map<int, int>m;
	m[5];
	print(m);
}

❤️最后

码神的开车之旅STL车型也算是圆满结束了,不知道你怎么样?关键是去找各个容器的相同点和不同点来进行对比的记忆,不知道你们有没有看到,就是在学了几个容器后,发现都是大同小异,不难,对吧?底层都是写好的,应用都是靠自己了,在更新完stl后,我也是要休息几天准备下大学生活了,感谢支持,停几天,给大家更新,还是老样子:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
机器学习--决策树算法(CART)
​ 我们知道,在ID3算法中我们使用了信息增益来选择特征,信息增益大的优先选择。在C4.5算法中,采用了信息增益比来选择特征,以减少信息增益容易选择特征值多的特征的问题。但是无论是ID3还是C4.5,都是基于信息论的熵模型的,这里面会涉及大量的对数运算。能不能简化模型同时也不至于完全丢失熵模型的优点呢?有!CART分类树算法使用基尼系数 来代替信息增益比,基尼系数代表了模型的不纯度,基尼系数越小,则不纯度越低,特征越好。这和信息增益(比)是相反的。
Kindear
2021/11/24
1.2K0
机器学习--决策树算法(CART)
机器学习 | 决策树模型(一)理论
决策树(Decision tree)是一种基本的分类与回归方法,是一种非参数的有监督学习方法。
数据STUDIO
2021/06/24
1.7K0
机器学习17:决策树模型
决策树分为两大类:分类树和回归树,分类树用于分类标签值,回归树用于预测连续值,常用算法有ID3、C4.5、CART等。
用户5473628
2019/08/08
1K0
机器学习17:决策树模型
最常见核心的决策树算法—ID3、C4.5、CART(非常详细)
决策树是一个非常常见并且优秀的机器学习算法,它易于理解、可解释性强,其可作为分类算法,也可用于回归模型。本文将分三篇介绍决策树,第一篇介绍基本树(包括 ID3、C4.5、CART),第二篇介绍 Random Forest、Adaboost、GBDT,第三篇介绍 Xgboost 和 LightGBM。
Datawhale
2019/11/05
6.4K0
最常见核心的决策树算法—ID3、C4.5、CART(非常详细)
《大话机器学习算法》决策树—看这一篇就够了
这是一个新的系列,主要讲机器学习的相关算法,希望想入门的你能耐心看完《写在前面的话》
小一不二三
2020/04/18
7550
决策树算法原理(下)
    在决策树算法原理(上)这篇里,我们讲到了决策树里ID3算法,和ID3算法的改进版C4.5算法。对于C4.5算法,我们也提到了它的不足,比如模型是用较为复杂的熵来度量,使用了相对较为复杂的多叉树,只能处理分类不能处理回归等。对于这些问题, CART算法大部分做了改进。CART算法也就是我们下面的重点了。由于CART算法可以做回归,也可以做分类,我们分别加以介绍,先从CART分类树算法开始,重点比较和C4.5算法的不同点。接着介绍CART回归树算法,重点介绍和CART分类树的不同点。然后我们讨论CART树的建树算法和剪枝算法,最后总结决策树算法的优缺点。
刘建平Pinard
2018/08/14
7790
决策树算法原理(下)
决策树学习笔记(三):CART算法,决策树总结
推荐导读:本篇为树模型系列第三篇,旨在从最简单的决策树开始学习,循序渐进,最后理解并掌握复杂模型GBDT,Xgboost,为要想要深入了解机器学习算法和参加数据挖掘竞赛的朋友提供帮助。
1480
2019/07/15
8770
决策树学习笔记(三):CART算法,决策树总结
【机器学习】决策树
本文介绍了 ID3,C4.5,CART三种基本的决策树模型。首先介绍了决策树的特征选择,包括信息增益,信息增益率、基尼指数、最小均方差分别对应分类树ID3、C4.5、CART、回归树CART。然后介绍了决策树建树的一般流程、对比分类树和回归树建树的区别。最后介绍了树模型中避免过拟合问题的剪枝方法,包括前剪枝和后剪枝。
yuquanle
2020/04/01
7520
【机器学习】决策树
C4.5决策树及CART决策树
信息增益比本质: 是在信息增益的基础之上乘上一个惩罚参数。特征个数较多时,惩罚参数较小;特征个数较少时,惩罚参数较大。惩罚参数:数据集D以特征A作为随机变量的熵的倒数。
用户10950404
2024/07/30
2390
C4.5决策树及CART决策树
决策树算法:ID3,C4.5,CART
对于基本树我将大致从以下四个方面介绍每一个算法:思想、划分标准、剪枝策略,优缺点。
zhangjiqun
2024/12/14
3720
决策树算法:ID3,C4.5,CART
西瓜书4-决策树
从西瓜书和统计学习方法中学习了决策树的相关知识,同时在网上查找了树的知识点,最重要的是二叉树和树3种的遍历方式
皮大大
2021/03/02
1.2K0
决策树与随机森林
首先,在了解树模型之前,自然想到树模型和线性模型有什么区别呢?其中最重要的是,树形模型是一个一个特征进行处理,之前线性模型是所有特征给予权重相加得到一个新的值。决策树与逻辑回归的分类区别也在于此,逻辑回归是将所有特征变换为概率后,通过大于某一概率阈值的划分为一类,小于某一概率阈值的为另一类;而决策树是对每一个特征做一个划分。另外逻辑回归只能找到线性分割(输入特征x与logit之间是线性的,除非对x进行多维映射),而决策树可以找到非线性分割。
西西木木
2020/06/02
1.5K0
决策树与随机森林
【白话机器学习】算法理论+实战之决策树
如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的, 常见的机器学习算法:
Datawhale
2020/03/04
7790
【白话机器学习】算法理论+实战之决策树
【一分钟知识】决策树-ID3,C4.5,CART
决策树是一种自上而下,对样本数据进行树形分类的过程,由节点和有向边组成。节点分为内部节点和叶子节点,其中每个内部节点表示一个特征或属性,叶子节点表示类别。决策树常用于分类问题于回归问题,完全生长的决策树模型具有简单直观、解释性强的特点。
zenRRan
2019/08/15
1.2K0
【一分钟知识】决策树-ID3,C4.5,CART
机器学习算法复习手册——决策树
本手册整理自机器学习各相关书籍、网络资料、个人的理解与实践。总体编写宗旨: ①一看就懂; ②用20%的文字,涵盖80%的内容。 至于剩下的20%,一般属于比较偏、难的部分,建议自行查询相关书籍资料学习。而只用20%的文字,则代表手册里面几乎没有废话,也只有极少数必要的例子。
beyondGuo
2019/10/29
4120
机器学习算法复习手册——决策树
机器学习(6)——决策树前言:
前言: 通过第前面的学习介绍了机器学习回归模型创建的流程,并且知道了机器学习要做的事情是找到目标函数,优化它,通过每次迭代都使目标函数值最小,最优解就是目标函数最小化时侯对应的模型参数。而这一章会介绍一种和回归模型流程相反的模型—决策树,它是通过建立树模型之后,才得到的损失函数,并且成为衡量决策树模型的指标。有时候数据特征众多且巨大,可以利用这种直观的树结构对数据特征进行切分,然后再构建模型。 本章主要涉及到的知识点有: 信息熵 决策树 决策树优化 树剪枝算法 决策树可视化 算法思想:从决策到决策树 本节首
DC童生
2018/04/27
1.4K0
机器学习(6)——决策树前言:
机器学习算法之决策树
"语言艺术是以善意为基础。变相的讽刺,拐弯抹角的谩骂,体现的不是机灵,而是素质问题,毕竟谁都不是傻瓜。
小闫同学啊
2020/02/26
6940
机器学习--决策树算法
在生活中,“树”这一模型有很广泛的应用,事实证明,它在机器学习分类和回归领域也有着深刻而广泛的影响。在决策分析中,决策树可以明确直观的展现出决策结果和决策过程。如名所示,它使用树状决策模型。它不仅仅是在数据挖掘中用户获取特定目标解的策略,同时也被广泛的应用于机器学习。
Kindear
2021/10/26
7180
机器学习(12)之决策树总结与python实践(~附源码链接~)
关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 前言 在(机器学习(9)之ID3算法详解及python实现)中讲到了ID3算法,在(机器学习(11)之C4.5详解与Python实现(从解决ID3不足的视角))中论述了ID3算法的改进版C4.5算法。对于C4.5算法,也提到了它的不足,比如模型是用较为复杂的熵来度量,使用了相对较为复杂的多叉树,只能处理分类不能处理回归等。对于这些问题, CART算法大部分做了改进。由于CART算法可以
昱良
2018/04/04
4.3K0
机器学习(12)之决策树总结与python实践(~附源码链接~)
决策树算法:ID3,C4.5,CART
其实用一下图片能更好的理解LR模型和决策树模型算法的根本区别,我们可以思考一下一个决策问题:是否去相亲,一个女孩的母亲要给这个女海介绍对象。
大数据技术与机器学习
2019/11/20
1.4K0
决策树算法:ID3,C4.5,CART
相关推荐
机器学习--决策树算法(CART)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验