自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(66)
  • 收藏
  • 关注

原创 【C++】智能指针

两个节点的资源没有被释放,因为循环引用的问题。初始化两个节点时,各自的引用计数为1,然后node1的next指向node2,使node2节点引用计数变成2;因为node1->_next = node2和node2->_prev = node1时,weak_ptr的_next和_prev不会增加node1和node2的引用计数,所以只要有引用计数变成0,就能释放资源了。它可以用一个对象管理一份资源,在对象构造时获取资源,对象析构时释放资源,并且在对象的生命周期中始终可以使用资源。这种方法其实也不行。

2024-05-19 13:32:07 1001 21

原创 【C++】异常

实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一旦有人随意抛异常,就不好了。所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了。////......_id是编号,_errmsg是具体错误信息。what()函数返回错误信息,记得要加上virtual,形成多态。

2024-04-12 20:11:34 1079 30

原创 【C++】lambda表达式

以上代码虽然可以实现自定义类型中的某个成员的比较规则,但是这样写是不是有些麻烦,每次实现一个algorithm算法,都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。这段代码捕捉列表后面要有小括号和mutable,因为捕捉列表里的a和b是常属性的,带上mutable可以取消常属性,有mutable不管有没有参数都要加上小括号。函数对象,又称为仿函数,即可以像函数一样使用的对象,就是在类中重载了operator()运算符的类对象。

2024-04-09 12:40:58 1169 12

原创 【C++】哈希之布隆过滤器

一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作。k为哈希函数的个数,这里有3个哈希函数,m为布隆过滤器的长度,n为插入元素的个数,ln2的大小约为0.69,推导出:4.34 * n = m,简化一下m与n的关系为:5n = m。插入元素时,不同的哈希函数计算出该元素的不同的映射位置,然后将要映射的位置标记为存在,即比特位为1。

2024-04-06 15:22:50 1046 8

原创 【C++】学习多态原理

用基类对象去调用,派生类对象给基类对象是切片,但注意:这过程中有拷贝构造出一个基类的对象,这个基类的对象所对应的虚表是基类的虚表,结果导致拷贝构造的基类对象都去基类对象的虚表中找虚函数,就没有调用派生类对象的虚表中的虚函数了。因为派生类继承基类得到基类的那部分的虚表,虚表里面的虚函数地址是基类的,如果不进行重写,在派生类对象的虚表中找到的虚函数依然是基类的,所以要对基类的虚函数进行重写,虚表中也同时完成了虚函数地址的覆盖,调用时就是派生类的了。注意:同一个类的对象,对应的是同一张虚表。

2024-04-05 14:47:10 782 7

原创 【C++】哈希之位图

一个整数等于32个比特位,根据位图的概念,用每个比特位是1还是0来确定一个数到底在不在,1个整数的32个比特位可以用来确定32个数据的存在,所以16G除以32等于0.5G,即512M,这就是开辟的空间大小,是不是节省多了。类的模板是非类型模板参数,传的是数据的大小。一个二进制比特位只有两种状态,要么为0,要么为1,如果某个数据在,则对应映射的比特位为1;每个数都有对应映射的比特位,将这个数除以32找到该数在数组中的位置,取模32找到映射的第几个比特位,1左移前面取模的位数,然后按位或将该比特位设置为1。

2024-04-02 21:47:35 1188 6

原创 【C++】新的类功能和可变参数模板

empalce系列中的emplace_back函数与push_back函数的功能是相同的,都是尾插数据。只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。对于深拷贝类对象,如果插入的是类对象时,两个没有区别;如果插入的是对象的参数,那么emplace系列函数会。对于浅拷贝类对象,如果插入的是类对象时,两个没有区别;如果插入的是对象的参数,那么emplace系列函数会。很明显是不行的,因为模板是编译时解析,for循环是运行时解析参数。

2024-04-02 12:38:10 624 8

原创 【C++】右值引用

引用是给对象取别名,本质是为了减少拷贝。以前我们学习的引用都是左值引用,右值引用是C++11新增的语法,它们的共同点都是给对象取别名。既然如此,有了左值引用,为什么还要有右值引用?右值引用具体是怎样的?以及它有哪些应用场景?接下来,会详细分析~~左值是一个表示数据的表达式,可以是变量名、解引用的指针和前置++。左值可以取地址和赋值,它出现在赋值符号的左边。如果定义的左值被const修饰,那么它就不能被赋值,但是可以取地址。//左值int a = 10;

2024-03-31 09:45:17 1070 31

原创 【C++】用哈希桶模拟实现unordered_set和unordered_map

顺序结构中(数组)查找一个元素需要遍历整个数组,时间复杂度为O(N);树形结构中(二叉搜索树)查找一个元素,时间复杂度最多为树的高度次logN。可以不经过任何比较,一次直接从表中得到要搜索的元素。构造一种存储结构,通过某种函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。主要有3种操作:插入——根据待插入元素的关键码,以此函数计算出该元素的存储位置并按此位置进行存放查找。

2024-03-24 18:22:09 1371 27

原创 【C++】用红黑树模拟实现set、map

set、map的底层结构是红黑树,它们的函数通过调用红黑树的接口来实现,红黑树一些接口需要通过树形迭代器来实现。set是k模型,map是kv模型,红黑树要不要写两份呢?答案是不需要,只用一份即可,通过仿函数来控制。T _data;,_col(RED){}红黑树有3个指针域,数据域用T来表示,如果是set,那么传过来的是k模型;如果是map,是kv模型。新增的节点的颜色默认是红色(根节点除外)。

2024-03-19 20:51:55 1029 22

原创 【C++】实现红黑树

红黑树也是三叉链结构(左指针、右指针和父亲指针),有一个新的存储位来记录节点的颜色,这里实现的红黑树是kv模型。RED,//红色BLACK//黑色,_kv(kv),_col(RED)//默认的新节点都是红色的{}

2024-03-15 21:00:48 1209 21

原创 【C++】AVL树的插入、旋转

AVL树是高度平衡的二叉搜索树,相比普通的二叉搜索树,它防止了变成单支树的情况。因为AVL树每插入一个新的节点,它都会调整使左右子树的高度差的绝对值不超过1,从而降低了树的高度,提高了搜索效率。左右子树都是AVL树左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)搜索时间复杂度O(log2nlog_2 nlog2​n有平衡因子控制高度差:右子树高度减去左子树高度AVL树是三叉链结构,即左孩子指针、右孩子指针和双亲指针,多了一个双亲指针方便找到上一个节点。

2024-03-12 16:23:25 1151 16

原创 【C++】set、multiset与map、multimap的使用

目录一、关联式容器二、键值对三、树形结构的关联式容器3.1 set3.1.1 模板参数列表3.1.2 构造3.1.3 迭代器3.1.4 容量3.1.5 修改操作3.2 multiset3.3 map3.3.1 模板参数列表3.3.2 构造3.3.3 迭代器3.3.4 容量3.3.5 修改操作3.3.6 operator[]3.4 multimap一、关联式容器谈到关联式容器,先来说说序列式容器,以前学习的vector、list、deque等就是序列式容器,它们的特点是底层为线性序列的数据结构,存储的是元

2024-03-03 17:32:06 1111 22

原创 【C++】二叉搜索树

还有一点,递归的话不需要循环那样得有一个parent来记录上一次的位置,因为从哪里递归下来、返回回去,都是确定好的,即从当前位置往左子树的方向下去,返回就从左子树的位置回去,右边一样的。这里要注意的一点是,因为是在类里写,每个成员函数都有隐藏的this指针,而递归写法是要带参数的,所以这里写中序遍历时,要有一个子函数来递归,后面的递归写法也要这样。删除,即将要删除的节点的值与它的左子树或者右子树中的某个节点的值进行替换,然后再把替换后的节点删除,与其他节点连接。与左为空类似,连接的是Cur的左子树。

2024-02-19 13:01:06 1161 26

原创 【Linux】make和Makefile

因为这3个时间里,相对而言访问的次数比修改更加频繁,即操作的时候我们一般都是查看文件较多,修改相对较少,所以系统就设定了一个规则,在短时间内查看文件它的Access时间不会发生改变,这么做其实也起到一个保护作用,因为前面说了,查看文件的操作的频次较高,如果系统频繁给Access时间调整,这样对系统来说比较“累”,所以这个Access时间在过了一定的时间段才发生改变。因为修改文件的内容,文件的大小也发生了变化,文件大小也是文件属性,即文件属性变化了,所以修改文件内容会连同文件属性一并修改。

2024-02-11 12:53:00 1222 19

原创 【C++】多态语法概念

概念:在继承关系下的不同类,调用同一个函数,产生不同的行为,叫作多态。图示:定义:必须通过基类的指针或者引用调用虚函数;被调用的函数必须是虚函数。类里的函数的返回类型前加上virtual就是虚函数,子类继承父类的虚函数叫作重写,重写的是虚函数的实现,该虚函数的返回类型、函数名、参数列表都要与父类相同(有两个特例,后面再谈)。public:cout << "全价" << endl;public:cout << "半价" << endl;

2024-02-11 12:51:42 424 6

原创 【C++】继承

以前我们的接触过函数复用,而继承就是一种类复用,减少代码的重复性。继承可以在原有类的基础上扩展新的功能,产生新的类叫派生类或子类,原有类叫基类或父类。比如说学生类和老师类,它们共同的成员变量有名字和年龄,这时就可以写个Person类来处理公共的成员变量,不需要学生类和老师类自己再写名字和年龄的成员变量,只要写自己的独有的那部分即可。

2024-02-04 12:44:11 1369 23

原创 【C++】list的模拟实现

list是带头双向循环链表,与vector的底层结构不一样,vector是连续的空间,list的每个节点是独立的空间。struct ListNode//节点类struct ListIterator//正向迭代器类struct ReverseIterator//反向迭代器类class list//模拟实现list类//获取第一个节点数据T& front()//获取最后一个节点数据T& back()

2024-01-25 19:49:06 1474 20

原创 【C++】stack、queue的使用及模拟实现

stack作为容器适配器,它的底层可以复用其他的容器,例如vector、list、deque,默认的情况下使用的是deque,deque兼具vector和list在实现上的功能,只是有些在效率上会有所差异。queue也是一种容器适配器,特点是先进先出,在一端插入元素,另一端删除或者获取元素。stack是一种容器适配器,它的特点是后进先出,只能在容器的一端进行插入和删除操作。queue的模拟实现与stack同理。

2024-01-24 23:24:44 449 11

原创 【C++】list的使用

但是会出现以上的情况,因为pos指向元素为3的节点,第一次插入是3的前面没有问题,但是第二次插入时pos还是指向元素3,所以插入999还是在元素3的前面插入。返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置。因为第一次删除pos位置的节点,该节点已经不存在了,第二次删除还是使用上一次的pos,所以会报错。list不需要扩容,它的每个节点是独立的一块空间,根据需求来进行新增节点或者删除节点。

2024-01-23 23:03:07 1076 7

原创 【C++】vector的使用及模拟实现

vector是一个可变大小数组的容器,与数组一样,vector也是一块连续的空间,可以像数组一样对元素进行高效的遍历访问,但是普通数组的大小是不变的,vector可以改变自身大小。vector是采用动态分配数组来存储数据,即插入新元素时要改变存储空间大小,往往要分配一个新的数组,然后把原来数组的元素转移到新的空间里。vector的尾插尾删效率高,中间插入和删除效率较低。

2024-01-16 19:37:26 1285 29

原创 【排序篇3】快速排序、归并排序

通过前面的两种方法可以发现:确定好某个元素的位置后,该元素的左右两个区间分别是小于这个元素和大于这个元素(以数组是1,2,3,4,5,6,7,8,9,10为例),也就是说要确定位置的元素是区分两个不同区间的标杆,所以这里可以使用前后指针法,用来区分两块区域。这与最后确定元素位置的交换有关,假设ki是数组元素,交换的是left指向的元素和ki,那么结果是left指向的元素变成了ki这个元素,但是数组左端的元素依旧没变。接下来分析单趟排序的实现。ki取的是下标,才能真正交换数组左端和left指向的元素。

2024-01-14 14:22:10 1132 13

原创 【排序篇2】选择排序、计数排序

计数排序采用相对映射的思想,开辟一块空间,该空间的范围为待排序的数组的最大值和最小值之差加1,并且每个元素初始化为0,然后待排序的数组只要是出现的元素就在临时空间对应的位置计数,最后从小到大恢复原来的元素重新放入数组,完成排序。从数组中选出最小值和最大值放在起始位置,直到排序完成。

2024-01-13 13:38:43 428 10

原创 【排序篇1】插入排序、希尔排序

注意:while循环的条件gap大于1并不是说gap不能为1,而是这里在前面的进入循环的时候就有可能为1了,记住gap是先缩小再使用的,进入循环时(还没有缩小)的gap是上次使用的gap。希尔排序与插入排序很像,单趟排序的思路基本相似,不同的是,插入排序的每次对比一个指向的元素是向前移动一个距离,希尔排序是移动gap个距离,从大到小,最后为1。再进行循环的判断,如果条件不是大于1的话,而是大于等于1,那么gap为1可以进入循环,然后1除1等于1,1+1等于2,就死循环了。

2024-01-13 08:45:47 618 12

原创 【Linux】Linux基础之权限

因为系统只识别拥有者是否有可读权限,也就是说,这个文件是yss创建的,同时目前的身份是yss,那么它就只看yss拥有者是否有可读的权限,只以第一次的识别为标准,后面的所属组是否有 r 它就不看了。很明显,这个文件的所处的目录是普通用户yss的,它的拥有者具有w写的权限,所以可以对它目录下的文件进行删除,不管那个文件是谁的。确实可以删除,可是回到最开始的问题,既然我(一个普通用户)创建的一个文件放在公共区域里,可以让别人读或者写,也有权利不让别人读或者写,但是防不住别人删了这个文件,该怎么办?

2024-01-07 20:19:27 2939 26

原创 【C++初阶】学习string类的模拟实现

前面已经学习了string类的用法,这篇文章将更深入的学习string类,了解string类的底层是怎么实现的。当然,这里只是模拟一些常用的,不常用的可以看文档学习。

2023-12-20 19:06:43 2448 26

原创 【C++初阶】STL之学习string的用法

STL是C++的标准模板库,里面包含了许多算法和数据结构,例如我们熟悉的顺序表、链表、栈和队列以及一些常见的算法等等,编程者想使用这些就可以直接从库中调用,不必再自己造轮子了。下面为STL内容的一张图:接下来,我们要学习STL中的string。string 是C++的一个类模板,字符串的类模板。要定义一个对象为字符串,就可以用string类型,说明它是一个字符串,相当于字符数组。

2023-11-24 20:34:10 1288 43

原创 【C++初阶】内存管理 && 初识模板

当对象是自定义类型时,malloc不方便自定义类型初始化,因为malloc只会开辟空间,free只会释放空间。

2023-11-16 13:31:45 349 31

原创 【C++初阶】类与对象(三)

这个引用成员变量,那么定义的地方在哪?就在初始化列表。2️⃣const成员变量与引用也是一样的,在私有的区域里只是声明,要定义的话必须在初始化列表。3️⃣上篇文章使用队列类的时候我们没有写队列类的构造函数,内置类型声明有缺省值使用缺省值,没有是随机值;自定义类型成员变量让编译器自动调用它的默认构造。复习下什么是默认构造:1.我们不显示写构造函数编译器默认自动生成的2.没有传参的3.全缺省的。

2023-11-12 21:16:02 381 33

原创 【C++初阶】类与对象(二)

构造函数——初始化析构函数——清理拷贝构造函数——使用同类对象初始化创建对象赋值运算符重载——一个对象赋值给另一个对象const成员函数——修饰this指针取地址重载——获取对象地址默认的意思是我们自己不写编译器自动生成,当然我们也可以自己写。1、写,应该怎样实现;2、不写,是否符合要求。

2023-11-03 21:01:22 423 31

原创 【C++初阶】类与对象(一)

/// 类体:由成员函数和成员变量组成//// 一定要注意后面的分号,与C语言的结构体同class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类的定义有两种写法,一种是声明和定义全部写在类里,另一种是分文件声明和定义分离,在做项目的时候或者代码规模较大以后者居多。int top;

2023-10-23 20:26:44 267 27

原创 【C++初阶】小白入门C++

从本篇文章开始就正式进入C++的学习了,C++在C语言的基础上增加了面向对象的思想,还有许多库,在使用上相比C语言大大提高了效率,同时在语法上也填上C语言的坑。本篇文章是介绍C++入门的基础语法知识,接下来我们一起往下看吧~在C++中,允许同一作用域中出现名字相同但类型/参数个数/类型顺序不同的函数,这类函数叫做重载函数。常用来解决功能类似数据类型不同的问题。return 0;Add(6);

2023-10-21 14:26:11 430 21

原创 【数据结构】二叉树的链式结构

如果没有要找的节点,返回空。如果这个二叉树不是完全二叉树,那么在第一个循环遇到空跳出后,它的后面还有节点,此时队列不为空,继续用前面的方法,定义一个临时变量获取队列头元素,判断是不是空,是空,删除这个空,继续判断(不管空与节点之间隔多少,它们都在队列里,因此队列不为空继续判断、删除,直到队列为空才停下);不是空指针,先进入它的左函数(左子树),在左函数中还是先判断是否为空指针,是,返回0,不是,接着还是先进入它的左函数,如果次时它的左函数的这个节点为空,就返回0,然后进入它的右函数,也是空,返回0。

2023-09-30 13:21:33 494 29

原创 【数据结构】树、二叉树的概念和二叉树的顺序结构及实现

之前我们学习了顺序表、链表以及栈和队列这些数据结构,但这些数据结构都是线性的(一对一)。接下来要学习非线性的数据结构——树(二叉树),相比前面的,树的结构更加复杂,话不多说,直接进入正题吧。

2023-09-29 16:54:41 1071 18

原创 【数据结构练习】单链表OJ题(二)

比如原节点13的random指针指向原节点的7,那么拷贝节点13的random指针则指向拷贝节点的7。用一个变量cur遍历链表,只要不为空每次进入循环先定义一个变量next记录原链表的下一个位置(cur在原链表的下一个位置,方便一次拷贝完找到),然后开辟一块空间copy为拷贝节点,把原节点的值赋给拷贝节点,再让cur的下一个地址为copy,copy连接next。它们的长度不一定一样长,所以要先计算出链表A和链表B的长度,让较长的链表先走长度差的距离,然后再同时走,直到两个链表相交,返回那个开始相交的节点。

2023-08-25 16:12:05 800 21

原创 【数据结构】实现栈和队列

入队相当于尾插,因为只有一个入口插入节点,所以直接在这个函数创建一个新节点。分两种情况:刚开始没有节点尾插、已有节点再尾插。如果没有节点,就不能再删了,所以要断言检查是否为空。这里的头删也要分两种情况:只有一个节点、一个以上的节点。栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。队列除了节点的结构体以外,还要再创建一个结构体,方便找到尾指针。因为栈的特点是出栈、入栈在同一位置,所以用数组尾插更方便。

2023-08-23 22:27:13 1139 18

原创 【数据结构】实现带头双向循环链表

之前我们已经学习了单链表,有了单链表的基础,现在开始学习带头双向循环链表~结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单。

2023-08-22 14:35:39 371 15

原创 【数据结构练习】单链表OJ题(一)

用一个变量cur遍历链表,要删除的节点是头节点,就是。

2023-08-21 15:57:06 419 10

原创 【C语言练习】数组OJ题

创建两个变量src和dest,让src去遍历数组(src的范围小于元素个数),如果数组中的元素与val相等,就跳过;当某个数组的全部放完了,直接把另一个数组依次往前插入就行(如果是num1还有元素没放完就不需要,因为num1就是它自己,num2有多余的元素需要有这个条件),然后定义一个遍历去遍历数组,只要是重复的数字就跳过,不重复就存放到数组中,每次存放有一个变量(k)加1,(数组是从0加到N,所以把0到N的数加起来减去数组中的值,结果就是消失的数字。时间复杂度为O(N)得到的就是右轮转k个的数组。

2023-08-20 16:15:56 429 12

原创 【数据结构】吃透单链表!!!(详细解析~)

上篇文章介绍了顺序表,这篇文章开始着重讲解链表了。链表有很多种:单、双链表,循环、非循环链表还有带头、不带头的链表。本篇的主要内容是单链表(无头,单向,非循环)。链表对比顺序表有哪些不同之处,接下来会带大家一起了解~1.头部和中间的插入删除效率都较低,时间复杂度为O(N)。需要挪动数据。2.空间不够用了,增容需要申请新空间拷贝数据释放旧空间。会有不小的消耗。(尤其是异地扩容)3.扩容会有一定的空间浪费。

2023-08-19 23:29:56 2961 19

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除