- 博客(61)
- 收藏
- 关注
原创 [C++]特殊类设计
单例模式:一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。第一次使用实例对象时,创建对象。多个单例实例启动顺序自由控制。缺点:可能导致进程启动慢;若两个单例有启动的先后顺序,则饿汉无法控制。由于派生类要调用父类的构造函数,所以将构造函数私有化。加上final关键字,表示该类不能被继承。
2024-12-05 11:12:49
270
原创 [C++]智能指针
RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做简单来说,智能指针是RAII思想的一种实现。
2024-07-30 00:37:36
602
原创 [C++]位图+布隆过滤器
位图,就是用每一位(bit)来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。如:数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。我们将每一个数据都以某种方式映射到位图中,那么一个位置就代表了其所对应的数据,一个数据只映射到其对应的位置中(一一对应)。
2024-07-14 17:21:44
402
原创 [C++]哈希
在顺序结构以及平衡树中,元素关键码(key)与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码(key)的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(log2 N),搜索的效率取决于搜索过程中元素的比较次数。理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素。如果构造一种存储结构,通过某种函数(HashFunc)使元素的存储位置与它的关键码(key)之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。
2024-07-14 13:22:52
1057
原创 [Linux]缓冲区
缓冲区,也称为缓存,是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,用来缓冲输入或输出的数据。这个保留的空间称为缓冲区。使用者发送。
2024-06-24 17:02:52
897
原创 [Linux]重定向
上层并不知道我们将1号文件描述符的指向改变了,printf()打印的本质是向1号文件描述符里面打印,具体1号文件描述符指向的是显示器,就向显示器打印,指向的是文件,就向文件里打印。所以这里,printf()就向log.txt里面打印了。重定向的 本质就是修改 文件描述符表 特定数组下标 里面的内容。
2024-05-31 13:42:00
948
原创 [C++]红黑树
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。性质:每个结点不是红色就是黑色根节点是黑色的如果一个节点是红色的,则它的两个孩子结点是黑色的对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
2024-05-29 12:50:53
740
原创 [Linux]文件/文件描述符fd
文件=内容+属性操作系统提供系统调用接口进程:打开的文件 = 1 : n操作系统来做操作系统在运行时,可能会打开很多文件,那么,操作系统该如何对文件进行管理呢?文件的属性与文件内容一样,在磁盘中同样有保存。我们使用对这些对象进行管理。那么,对于文件的管理,就转换成了对链表的增删查改。被打开的文件在内存中,未被打开的文件在磁盘中。所有的文件操作,都是在内存中操作的。因此,研究文件操作的本质就是研究进程和被打开文件的关系。
2024-05-26 17:22:21
1031
原创 [Linux] shell程序编写
Linux严格意义上说的是一个操作系统,我们称之为“核心(kernel)“ ,但我们一般用户,不能直接使用kernel。而是通过kernel的“外壳”程序,也就是所谓的shell,来与kernel沟通。
2024-05-24 16:19:05
165
原创 【C++】AVL树
AVL树是一种平衡的二叉搜索树,它的特点是任何节点的两个子树的高度最大差别为1,也就是说它是高度平衡的。AVL树的查找、插入和删除的时间复杂度都是O(log n),但是插入和删除可能需要通过旋转来调整树的结构。AVL树是两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明的,达到降低树的高度,从而减少平均搜索长度的目的。
2024-05-23 17:09:11
539
原创 [linux]进程控制——进程等待
解决子进程僵尸问题带来的内存泄漏问题(是必须的)需要通过进程等待的方式,获取子进程退出的信息。(不是必须的,但是系统需要提供这样的基础功能(可以不用,但不能没有))进程等待能够回收子进程僵尸状态,Z->X如果子进程没有退出,父进程必须在wait上进行阻塞等待,直到子进程僵尸,wait自动回收,返回。当一个进程异常(收到信号),exit code是没有意义的。判定有没有收到信号,exit sig:0(sucess)exit sig:0,exit code: 0 :代码跑完,结果正确。
2024-04-21 11:19:29
701
1
原创 [linux]进程控制——进程终止
那么我们为什么要返回(return)0 呢?其实,main函数也是一个函数,它也会被调用,所以谁调用main函数,这个返回值就会返回给谁。执行以上程序,我们可以看到return返回值写的是3。我们可以通过 echo $?查看进程退出码:main函数的 返回值,就叫做进程的退出码。0 -> sucess (0表示成功)
2024-04-15 13:26:44
781
原创 [linux]进程控制——进程创建
在linux中fork函数从已存在进程中,创建一个新进程。新进程为子进程,而原进程为父进程。返回值:子进程中返回0,父进程返回子进程id,出错返回-1。
2024-04-14 16:51:09
927
原创 [C++]map && set
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的。Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器。key: 键值对中key的类型。T: 键值对中value的类型。
2024-04-11 12:13:48
641
原创 [C++]二叉搜索树
对于二叉搜索树的插入操作,我们将需要插入的key值与当前结点(初始结点是root结点)比较,若小于该结点的值,则往左子树走;若大于该结点的值,则往右子树走。对于二叉搜索树的查找操作,我们将需要查找的key值与当前结点(初始结点是root结点)比较,若小于该结点的值,则往左子树走;若大于该结点的值,则往右子树走。若走到空,则说明没有这个值,返回空指针。若找到该值,则返回该值的结点。走到空结点的时候,那么这个位置就是这个key值的归宿。使用中序遍历二叉搜索树时,我们得到的是一个递增序列。
2024-02-18 22:04:18
479
原创 [C++]多态
重载:两个函数在同一作用域函数名、参数相同重写:两个函数分别在基类和派生类的作用域函数名、参数、返回值都必须相同(协变例外)两个函数必须是虚函数重定义:两个函数分别在基类和派生类的作用域函数名相同两个基类和派生类的同名函数不构成重写就是重定义。
2024-02-15 12:20:39
1027
原创 [C++]继承(续)
在public继承时,父类和子类是一个“is - a”的关系。子类对象赋值给父类对象/父类指针/父类引用,我们认为是天然的,中间不产生临时对象,也叫作父子类赋值兼容规则(切割/切片)。
2024-02-01 14:30:08
752
原创 [C++]初识继承
/ 派生类↓ 继承方式↓ 基类↓private:继承基类成员访问方式的变化(即为类成员的访问限定符与继承方式的访问限定符中权限最低的那一个(如:public和protected,则为protected)):基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
2024-01-31 21:48:51
445
原创 [C++]模版(进阶学习)
模板参数分类:类型形参与非类型形参。类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。注意:1.浮点数、类对象以及字符串是不允许作为非类型模板参数的。(即只能使用整型(字符亦可,本质不变))2. 非类型的模板参数必须在编译期就能确认结果。(即必须传确定的值,不能传变量)
2024-01-31 14:25:46
525
原创 [C++]priority_queue——优先级队列(含模拟实现)
priority_queue 是容器适配器,它提供常数时间的(默认)最大元素查找,对数代价的插入与释出。可用用户 提供的Compare更改顺序,例如,用 std::greater 将导致最小元素作为出现。用工作类似管理某些随机访问容器中的,优势是不可能突然把堆非法化。
2024-01-27 07:07:46
434
原创 【Linux】[gdb]Linux环境下如何调试代码
(1)list/l (显示代码)功能:打开代码,显示代码及行号注意:一次list 可能不能完整显示所有代码,所以需要多次回车(直接回车就是上一个命令)(也可以再次使用list命令,效果一样)。此外,我们还可以使用 l 数字(比如: l 1),使得从第1行开始显示
2023-10-04 21:22:15
314
原创 [C++] 迭代器失效示例
我们以模拟实现vector为例。这里的pos会变成野指针。当扩完容后,由于空间的改变,_start和_finish和_endofstorage的指向就变了。所以pos失效。
2023-08-18 07:34:49
195
原创 【C++】速识模板(template<class T>)
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。
2023-08-12 12:45:18
1358
原创 【C++】友元(含内部类)
友元函数可访问类的私有和保护成员,但不是类的成员函数友元函数不能使用const修饰友元函数可以在类定义的任何地方声明,不受访问限定符(public/private/protected)限制一个函数可以是多个类的友元函数友元函数的调用与普通函数的调用原理相同
2023-08-11 18:47:46
243
原创 [C++] 自定义的类如何使用“cout“和“cin“?(含日期类实现)
在C++中,“cin”和"cout"可以说是区别于C语言的一大亮点。但是,它的自动识别类型,其本质不过是运算符重载。若真到了能够“自动识别”的那一天,人类大概也能进入新的纪元了罢。对于我们自己写的类,想要用cout,cin,当然是可以的,我们只需自己写它的重载即可。本文将以“cout”为例。
2023-08-10 14:22:49
951
1
原创 【C++】内联函数(inline)
inline对于编译器而言只是一个建议 ,编译器会自动优化,如果定义为inline的函数很长或者是递归函数等,编译器优化时会忽略掉内联。长函数(10行以上,但是不同的编译器不同) 或者有递归的函数不适合使用作为内联函数, 因为调用的地方很多,展开后程序可能会一下变得很大。inline不建议定义和声明分离,分离会导致链接错误,因为inline被展开(在调用的地方),就没有函数地址了,链接就会找不到。有了inline ,就不需要使用c的宏,因为宏很复杂,很容易出错。release 版本不会建立栈帧。
2023-08-08 21:25:30
190
原创 【C++】常用到的“using namespace std;”到底是什么?
在初学C++时,在包含完头文件之后,我们常常会看到这么一句话:using namespace std;首先需要声明的是:它不是什么“固定动作”,不是必须这么写的。
2023-08-08 19:22:11
2704
原创 快排变慢排?怎么个事儿?(快速排序非递归实现)
我们知道,快排是一种很好的排序算法。但是在极少数的一些情况下,“快速排序”好像名不副实了。比如:。。。。。这样的数列。这样,我们就得到了一个很可惜的结论:快排不是万金油。但是,这是指的的快排,我们可以写的快速排序,来看看是否能解决这个问题。
2023-07-13 21:09:39
624
原创 【数据结构】【堆】 堆排,TOPK问题
我们将堆顶数据与最后一个数据进行交换,然后把堆的最后一个位置排除在外(即它不参与后续的调整),对交换后的堆顶数据进行向下调整,如此,堆顶存放的就是次小的数据。每次取出磁盘(或其它地方)的数据与堆顶数据进行比较,比堆顶数据大就进堆,然后向下调整。注意:不能构建成大堆,因为当堆顶的数据是最大的数据时,其它数据都无法进入堆。我们重复以上过程,那么就能依次选出最小的,次小的,次次小的······要找到最大的k个数据,我们就需要构建一个K个容量的小堆。在构建好小堆后,堆顶的数据就是最小的。如果要排降序,就构建小堆。
2023-05-31 13:34:03
511
原创 [数据结构] 【C语言】循环队列实现
设计你的循环队列实现。循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
2023-05-20 22:13:04
115
原创 【数据结构】[LeetCode138. 复制带随机指针的链表]
给你一个长度为n的链表,每个节点包含一个额外增加的随机指针random,该指针可以指向链表中的任何节点或空节点。构造这个链表的。深拷贝应该正好由n个节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的next指针和random指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。。例如,如果原链表中有X和Y两个节点,其中。那么在复制链表中对应的两个节点x和y,同样有。返回复制链表的头节点。用一个由n个节点组成的链表来表示输入/输出中的链表。
2023-05-11 20:09:05
484
原创 【数据结构】[环形链表](LeetCode142. 环形链表 II)给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(如果pos是-1,则在该链表中没有环。pos,仅仅是为了标识链表的实际情况。链表。
2023-05-11 18:47:12
415
原创 【数据结构】删除二叉树中的结点;树与二叉树的相互转换(含二叉树/二叉排序树的基本运算)
(1)首先判断要删除的结点是否存在,如果不存在则直接返回NULL。(2)如果要删除的结点小于当前结点,则递归删除左子树中的结点。(3)如果要删除的结点大于当前结点,则递归删除右子树中的结点。(4)如果要删除的结点等于当前结点,则分四种情况进行处理:情况1:要删除的结点是叶子结点,直接删除即可。情况2:要删除的结点只有右子树,将右子树替换当前结点即可。情况3:要删除的结点只有左子树,将左子树替换当前结点即可。情况4:要删除的结点既有左子树又有右子树,将右子树中的最小值替换当前结点即可。
2023-04-26 17:05:13
1681
原创 【数据结构】交换二叉树每个结点的左右子节点+计算二叉树的最大宽度等实现(C语言)
【数据结构】交换二叉树每个结点的左孩子和右孩子、计算二叉树的最大宽度、二叉树查找值为x的节点、二叉树深度/高度、二叉树第k层节点个数、二叉树叶子结点个数、二叉树节点个数、前序+中序+后序遍历
2023-04-05 16:09:31
510
原创 【C语言】 [程序环境】简析翻译环境、执行环境
在ANSIC的任何一种实现中,存在两个不同的环境。第一种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。第二种是执行环境,它用于实际执行代码。
2023-04-03 17:25:46
233
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人