e哥基础课堂回顾关于stl的六种使用方法

我发现在e哥的基础课中,只讲了map,bitset还有set,还有几个常用的没讲,所以我今天打算一起全部讲了算了,如果想看本章的出处可以去b站关注Erik_Tse。

                                          **stl的几种使用方法**

NO.1 vector

                                                **先上图**

在这里插入图片描述

首先我们vector的定义从oi wiki中可以了解到,是一个内存连续,可变长度的数组,那它与我们常用数组有什么区别呢?

1,vector与数组第一个区别就是数组它是固定的空间范围,不可被修改,但是vector可以,vector它是动态的,可以根据需求进行扩展。

2,vector可以进行删除和增加,这一点数组是不能改变的,这也是为了我们在写算法的过程中以防万一而准备的。

上面的内容我相信大家看了一遍后就会有所了解,我来解释一些细节问题!
1,看到初始化在vectorv的T这个主要是数据类型,比如可以用int ,char等类型。

2,在遍历中我们看到有一个v.size()-1,这个不能使用,因为刚开始进行判断时,v.size()里面有可能是零,如果减一那就会变成-1了,在引用中两种不同的方法一个是拷贝,一个是引用,相较于前者后者用的范围更广,因为引用可以修改前面数组或者已经被定义好的值,但是拷贝不行。

3,emplace_back(y)是干什么的呢?这个也是stl中一个用法 ,它的功能就是在用于在容器的末尾直接构造一个新元素,且比push_back更高效还能避免不必要的拷贝和移位,但是我还是建议大家用push_back()因为大多数算法题用这个就行了,下面是我用gpt搜索的的内容,大家看看了解就行。

优点
效率:emplace_back 直接在容器内存中构造对象,避免了临时对象的创建和移动,通常比 push_back 更高效。

简洁性:构造函数参数直接传递给 emplace_back,减少了代码复杂度。

应用场景
(1)动态添加对象:当你需要动态地添加新对象到容器中,并且对象构造较复杂时,emplace_back 通过直接构造对象可以提高性能。

(2)优化内存使用:通过避免多次拷贝和移动,emplace_back 可以减少内存消耗和提高程序性能。

(3)总结来说,emplace_back(y) 在算法和容器操作中,用于在容器末尾直接构造并添加新元素,是提升效率和简化代码的一种方法。

4,vector g[]这个主要是应用在存图比如二叉树和线段树中,挺常用的。

5,lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找 第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。在lower_bound中我们一般用在二分场景比较多,还有upper_bound也是,一个是大于或者等于,一个是大于。
在洛谷P1102中这个题就可以用lower和upper一起连用。

6//这个排序去重很重要,请务必背会

sort(v.begin(),v.end());//排序
v.erase(unique(v.begin(),v.end()),v.end());//去重

NO.2 stack

先上图!
在这里插入图片描述

                                                    **stack栈**

first in last out:先进后出,与之相对应的是我们后面要讲的queue,那先进后出是什么意思呢?
也就是我们越早放进去的数,后面越晚出来,因为把栈想象一个放数字的容器,越先放下去的,越在底层,而我们拿出来的时候是从上到下,所以这就是先进后出的原因。
哦,对对对,还有一件事情,很重要,刚想起来!
在这里插入图片描述
千万不能这么写的啊!
LIFO 表达的是 当前在容器 内最后进来的最先出去。你这样写是先进先出,是queue的用法

1,入栈和出栈以及初始化就不用说了,也就是push和pop还有push_back的应用,记得出栈的时候要保证stack里面非空,不然会RE的

2,stk.empty()也就是检测stack里面是否非空,然后也可以用stk.top(),也就是返回栈顶的元素(不会自动删除栈顶),一般与pop连用,这个要牢记!代码如下:
在这里插入图片描述
3,右边的内容是,我们如果知道DFS的话那这个算法就是基于栈,深度优先法,代码就是e哥所写的那样
DFS用法

NO.3 queue

记得别读成Queen了,有不少人发音错误,比如我。

先上图
queue的用法

first:对于queue来说很多都与stack相似,比如push,size,还有empty,但是这回pop要与front连用,然后就是上面stack所说的queue是first in first out就是先进先出这一点与后面BFS(广度优先)的内容相关,我们后面再说。

second:对于queue来说除了队头和队尾,中间的那一部分是不能被使用的,这是为了增加queue的安全性,也是方便大家更好理解,下面通过一段代码来展示

                                          这是没有用node的代码方式

在这里插入图片描述
在这里插入图片描述

                                             这是用了node的代码

在这里插入图片描述
在这里插入图片描述

                                              要注意的内容

在这里插入图片描述
在这里插入图片描述

                                                 这里是要解释的内容,

第一对于c++来说,它并不能自己取出一个元素,而是需要我们去表达一段代码,它才能理解就是上面q.size()那一段,如果不加的话那就RE了。

第二将q.size()转为q.empty也是可以的。

第三如果将q.size()这段内容放在push下面就不用来表示元素的个数了。

第四为什么back只有四个呢?因为刚开始i=1时 ,q.size()里面是空的,所以就少了一个输入值,这才是比答案少一个的原因。

NO.4 map

先上图在这里插入图片描述

                                        首先我们来解释什么是map?

在编程中,map(也叫哈希表、字典或关联数组)是一个数据结构,用于存储键值对。每个键(key)对应一个值(value),并且可以通过键快速查找、插入或删除对应的值。map的核心特性是高效的查找和管理数据。

它还有什么功能呢?
1,键值对存储:每个元素由键(key)和值(value)组成,键是唯一的。
2,快速访问:通过键可以快速查找、插入、更新和删除值,通常时间复杂度为O(1)到O(log n)。
3,键的唯一性:每个键在map中只能出现一次。
4,实现方式:常见实现包括哈希表(基于哈希函数)和树结构(如红黑树或AVL树)。

下面是map和multimap的图(multimap和map的区别就是键值对)
在这里插入图片描述
在这里插入图片描述
tip:有一点需要说明,除了map后面我们要学习的priority_queue也是当自己定义结构体时要重载小于号!

               下面是map的用法与上面vector和stack还有queue相似,但是多了find和operator(重载)

在这里插入图片描述

                                        下面是map迭代器的使用条件和引用方式

在这里插入图片描述

NO.5 priority_queue

先上模型图
在这里插入图片描述
那priority_queue的定义是什么呢?
first:priority_queue 是 C++ 标准库中的一个容器适配器,用于实现优先队列。优先队列是一个特殊的队列,其中每个元素都有一个优先级,队列总是返回优先级最高的元素。

second:priority_queue有个默认行为,就是priority_queue 默认实现为最大堆,即优先级最高的元素最先被访问。如果你需要最小堆(即优先级最低的元素最先被访问),可以通过提供一个自定义的比较函数来改变默认行为。

third:(小根)堆主要支持的操作有:插入一个数、查询最小值、删除最小值、合并两个堆、减小一个元素的值。

对于priority_queue它与map和后面要学的set很多相似的地方,如图:
在这里插入图片描述
在这里插入图片描述

                                                    用法也很类似

在这里插入图片描述补充一点

tip:这里e哥说到priority_queue跟vector还有set和不一样的位置就是迭代器,为什么priority_queue没有迭代器呢?
答案我去GPT还有csdn上搜索了一下,原因如下:

  1. 底层实现的复杂性
    priority_queue 通常使用 堆(例如最大堆或最小堆)作为其底层数据结构,堆是一种特殊的树结构,不同于其他容器如 std::vector 或 std::list。堆的特点是它们的元素不符合特定的顺序(除了堆的根节点具有最大或最小值外),因此从堆中获取所有元素的顺序是复杂且不一致的。

  2. 迭代器的定义
    迭代器通常需要提供以下功能:
    遍历容器中的所有元素。
    支持随机访问(对于某些容器)或顺序访问。
    由于 priority_queue 的元素在堆中没有定义严格的线性顺序(即只有根节点有一个明确的优先级),迭代器很难定义和实现。对于 priority_queue,元素的排列和顺序是高度依赖于堆的性质的,而不是线性结构。

总结
priority_queue 设计为专注于优先级操作而不是元素遍历,因此没有提供迭代器。其底层堆结构的特性和设计目标使得迭代器在这种数据结构中不适用。对于需要支持迭代的有序容器,可以选择其他容器类型如 std::vector 或 std::set。

NO.6 set

先上模型图
在这里插入图片描述
set的定义如下:
set 是关联容器,含有键值类型对象的已排序集,搜索、移除和插入拥有对数复杂度。set 内部通常采用 红黑树 实现。平衡二叉树 的特性使得 set 非常适合处理需要同时兼顾查找、插入与删除的情况。

tip: 那对于红黑树大家了解多少呢?
我的理解就是
1,每个节点是红色或黑色。
2,根节点是黑色。
3,每个叶子节点(NULL 节点)是黑色。
4,红色节点不能有红色子节点(即不能有两个连续的红色节点)。
5,从任意节点到其每个叶子节点的所有路径都包含相同数量的黑色节点(黑色高度)。
6,红黑树一般都用set和map来解决问题

总结:这些特性确保了红黑树的平衡性,避免了树的高度增长过快,保证了插入、删除和查找操作的时间复杂度为 O(logn)如果大家看不懂那就看看下面黑马程序员给的图
在这里插入图片描述

                                      下面就是相同的定义

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

                                        下面是不同的内容,很重要!

在这里插入图片描述在这里插入图片描述

                                       tip:set的用法大概内容就这些了,over!

OK,那么stl中六个使用方法已经全部讲完了,最后送个大家一段话:**今天的你,将承载昨天的自己继续生活下去,你无法改变过去,但可以选择创造现在,这之后,明天的你又会承载今天的你,继续走下去。**这是第二次投稿,如果有需要改进的点还希望大家能够指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值