- 博客(31)
- 收藏
- 关注
原创 function包装器和bind包装器
前面要加一个static是因为:这个函数是在类中,类成员函数一般都是由对象去调用的,这里只想要用它的地址 加上静态关系后,就不需要依靠对象调用了,光写函数名就能代表函数的地址了。这些都是可调用的类型对象,这就会导致模板的效率低下。以前想把那些可调用对象存在同一个vector中是几乎不可能的,现在借助包装器,将可调用对象类型统一后,就可以存储了。因为统一后,可以将不同的可调用对象都存储在同一个容器中,方便管理。此外,还要注意在写类型时,被绑定的参数的类型就不需要写在function中了。
2024-06-22 10:27:27
948
原创 lambda表达式
因为是值拷贝,此时捕捉列表中的变量是个中间临时变量,因此具有常性。其实lambda的底层是仿函数,实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的。我们无法显式的写出它们的类型,因为类型名称是编译器自动生成的,我们是不知道的,所以也只能用auto去自动推导类型。它保证了每个lambda所生成的仿函数的类名不会重复,也因此导致了每一个lambda对象的类型是不一样的。仿函数其实是类,类中只重载了operator()运算符的,这个类的对象可以像函数一样使用。
2024-06-21 11:18:12
1095
原创 万能引用与完美转发
因为我们说的万能引用最核心的因素在于,模板参数T是可以通过形参val推出来的,而这里的T并不是通过val推导出来的,而是在这里。归根结底是因为,这里的T是通过形参t推导出来的,假如实参是10,那么T就是。也就是说,右值引用会被默认识别为左值,如果想让其保持原本的属性,那么就用完美转发。到这里就和我们在右值引用中所讲的过程一样。在万能引用中说到:模板中出现&&不是右值引用,而是万能引用。中,实参传递到t中,不论实参是右值还是左值,t始终是个左值。这一调用,并不能调用到右值引用版本的insert,后面的。
2024-06-21 11:07:44
628
原创 红黑树的性质和实现
假设插入的是红节点:如果其父亲是黑节点那么一点问题都没有;对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。假设插入的是黑色节点,那么路径之间的黑节点的个数不再相同,所有路径都出现了问题。这里向上处理是个循环,而循环的结束条件为:g的父亲不存在或者g的父亲存在且为黑。红黑树,在每个节点上增加一个存储位表示节点的颜色,可以是RED或BLACK。此外cur并不一定是新插入的节点,有可能是正好向上调整到这个节点。约定:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点。
2023-11-06 16:12:26
195
原创 AVL树性质和实现
AVL树是一棵绝对平衡的二叉搜索树,其要求每个节点的左右子树高度差的绝对值都不超过1,这样可以保证查询时高效的时间复杂度,即log2Nlog_2 (N)log2N。但是如果要对AVL树做一些结构修改的操作,性能非常低下,比如:插入时要维护其绝对平衡,旋转的次数比较多,更差的是在删除时,有可能一直要让旋转持续到根的位置。因此:如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(即不会改变),可以考虑AVL树,但一个结构经常修改,就不太适合。
2023-11-06 16:10:26
604
原创 C++栈和队列
stack和queue与之前的容器有所区别,它们两个是容器适配器:是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素。容器适配器是一个封装了序列容器的,它在一般序列容器的基础上提供了一些不同的功能。之所以称作适配器类,是因为它可以通过适配容器现有的接口来提供不同的功能。比如充电器的头就是一个电压适配器反向迭代器也是一个适配器,是用正向迭代器转换出来的。
2023-08-30 16:14:47
83
原创 类和对象基础知识
class 类名成员变量成员函数类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数类中成员变量的定义写在类的前面还是后面都无所谓。因为类是一个整体,既会向上搜索也会向下如果一个类中什么成员都没有,简称为空类。空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
2023-03-25 15:21:42
433
原创 C++类和对象(初)
class 类名成员变量成员函数类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数类中成员变量的定义写在类的前面还是后面都无所谓。因为类是一个整体,既会向上搜索也会向下。
2023-03-17 19:42:08
739
1
原创 数据结构之各种排序方法
上述排序都是内排序(在内存中排序),但归并也可以是外排序(在磁盘中排序。当数据太大时,内存中放不下)我们将同时间复杂度的进行比较。
2023-01-12 16:08:31
844
原创 shell的运行原理和Linux中的权限
每组中的每个字符的位置的所表示的权限是确定的:第一个代表可不可读,第二个代表可不可写,第三个代表可不可执行。在linux中外壳程序把用户的输入操作通过命令的形式收到,然后将指令传递给操作系统,操作系统处理执行完后,再将结果传给shell,最后再给用户。一个文件有两种权限,一个是起始权限,在创建文件之处系统设定的;如果你给指令前带上sudo,执行这个指令的并不是以你的身份执行的,而是以root的身份执行的。完整描述一个文件的权限:拥有者的权限+所属组的权限+other的权限+拥有者是谁+所属组是谁。
2023-01-08 19:44:02
1028
原创 队列的实现及相关操作
/定义队列链表的结点 typedef struct QListNode {} QNode;//定义队列 typedef struct Queue {int size;} Queue;主体结构是,这是我们定义的队列,由指向头尾结点的两个指针和队列长度三个要素组成//在单链表中是没有这个结构体的。在这里存在的意义是队列需要头尾两个指针,所以就定义了这个结构体。单链表中只要指向头结点的指针即可指向头尾结点的指针,分别用于实现头删和尾插这里size存在的意义是:以空间换时间。
2022-11-24 20:39:15
412
1
原创 栈的实现及相关操作
/栈的容量 int top;//表示指向栈顶元素的下一个位置 } ST;这里和顺序表不同的是,这里没有size来表示栈的有效长度。取而代之的是top。
2022-11-24 20:38:09
661
原创 移除链表中指定元素-三种实现方法
这种方法就是分三种情况进行讨论:头删、尾删、中间删,比较容易想到,但实现起来也相对麻烦。我们可以从两个角度出发看这个题目:一个是需要删除的元素,另一个是需要保留的元素。链表不比顺序表,链表新建所开辟的额外空间是常数阶,不会造成空间复杂度的提升。大致代码与方法二相同,只不过是带哨兵位的头结点可以简化尾插。因此我们可以新建一个链表,将非删除元素尾插进来。,请你删除链表中所有满足。的节点,并返回 新的头节点。给你一个链表的头节点。
2022-11-07 17:01:59
4313
原创 【力扣原题讲解】合并两个有序数组成为一个新有序数组
以前我们做过类似的合并数组的题目,那时我们会开辟一个新空间,两个数组相互比较,将较小项依次放入新数组,最后输出新数组。而这里的话,我们采取一个更加巧妙的方法,不用开辟额外空间。具体思路是这样的:这里我们不能通过两个数组比较,将较小值放在。中,使合并后的数组同样按非递减顺序排列。但是我们可以反过来,先将较大值放在。给你两个按非递减顺序排列的整数数组。注意:由于最终的合并数组是。个元素表示应合并的元素,后。的前面,这有可能会覆盖了。个元素为 0,应忽略。
2022-11-03 17:32:21
323
原创 【力扣原题讲解】原地删除数组中的重复项
请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度,元素的相对顺序应该保持 一致。这里对上面的输出进行解释:函数应该返回的新长度为3,并且原数组nums的前三个元素被修改为1,2,3.看过我写的“原地删除数组指定项”那篇博客的同学,应该晓得这里还可以从另一个角度去看,即令。看过我写的“原地删除数组指定项”那篇博客的同学,应该晓得这里还可以从另一个角度去看,即令。其实这题和之前的“原地删除数组指定项”的解题思路差不多,方法都是。对“原地删除数组指定项”这题陌生的可以看我之前的博客。
2022-11-03 16:52:36
448
原创 【力扣题目讲解】原地删除数组中指定项
对上面的输出做一个解释:函数应该返回新的长度3,新nums中的前三个元素是0,3,2。并且,这三个元素可以为任意顺序,而且你不需要考虑数组中超出新长度后面的元素。你不需要考虑数组中超出新长度后面的元素。那么我们该任何实现原地删除数组值呢?的元素,并返回移除后数组的新长度。要求空间复杂度为O(1)
2022-11-03 15:17:51
207
原创 详细讲解算法的时空复杂度
而这里的函数栈帧并不会因为新的函数栈帧的开辟而销毁上一次开辟的,因为每一次递归,两个函数栈帧之间是有联系的,如果将某层栈帧销毁后,那么下面的函数将无法完成“归”的操作。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但其实右侧的递归调用所开辟的函数栈帧是与左侧的函数栈帧是相同的,也就是说两侧所用的空间是相同的。在数据结构的时间复杂度计算中,只有以2为底的,可以忽略底数。衡量一个算法的好坏,看的不是代码的简洁程度,而是算法的效率,即算法的复杂度。
2022-10-29 10:53:05
1934
原创 详细介绍预处理#define和编译链接等有关知识
预编译阶段预编译的操作对象是源文件(即.c文件),是将源文件中,所用的头文件进行包含注释的删除#define定义的符号的替换预编译阶段完成的操作被称为文本操作,尽管进行了这些操作,但预编译阶段的代码仍然是C语言代码编译阶段把C语言代码转换成了汇编代码,转换过程中做了这些事情:语法分析、词法分析、语义分析、符号汇总这里重点说一下符号汇总。编译器会在编译阶段将所有源文件的全局符号给汇总起来(包括:全局变量名、全局函数名、main等)汇编阶段把汇编代码转换成二进制代码形成符号表。
2022-10-17 10:42:14
1164
原创 C语言数据的存储详解
所有的整型都分有 signed和 unsigned两种void表示空类型,通常用于函数的返回类型、函数的参数、指针类型。任何数据类型变量的地址都可以放进空类型的指针,但此指针不可以被使用,只能作为地址的临时存放。
2022-08-20 09:54:35
2204
4
原创 关于sizeof和strlen的区别详述
本篇文章是作者自己对于sizeof和strlen的理解、总结,有写错的、写的不好的地方还请指正、包容)
2022-07-27 10:48:01
219
3
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人