自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 搜索二叉树的认识以及底层实现

所谓的搜索二叉树其实就是具有特殊规则要求的二叉树。搜索二叉树要求我们每一个子树都应该满足其左孩子节点当中存储的值都应该小于父节点当中存储的值,其右孩子节点当中存储的值都应该大于我们父节点当中存储的值。搜索二叉树结构如下图所示:只要我们满足这样的规则就说明我们的二叉树是一颗搜索二叉树。

2024-09-17 16:57:35 1192

原创 C++当中的多态(三)

编译器会自动将继承A的虚函数表当中对应的函数地址进行覆盖得到一个完整的派生类虚函数表A,同样的对于读书与B类的虚函数进行重写的时候,也会对相应的函数地址进行覆盖得到一个完整的派生类虚函数表B。同时我们A的虚函数表被D类所继承,如果D类对A类进行虚函数的重写操作,会直接使用新的虚函数地址覆盖我们原有的虚函数的地址。思考一下:我们的虚表可以进行修改吗?使用基类A的指针进行访问C类重写的函数,调用的应该是C类当中的重写之后的虚函数,使用基类B的指针进行访问C类重写的函数,调用的应该也是C类当中重写之后的虚函数。

2024-09-12 21:21:28 1008

原创 C++当中的多态(二)

相信大家在刚开始遇到这三种概念的时候都会产生疑惑。重载,重写,重定义很像诶,那么这三者有什么区别呢?我们需要注意什么吗?函数重定义的概念在我们的继承章节当中提到过。当我们的派生类存在跟我们基类函数名完全相同的函数的时候,就构成了函数的隐藏。对于函数隐藏来说我们并不要求参数类型一致,不管我们参数相不相同,只要函数分别在基类跟派生类当中,只要不满足我们重写的要求的同名函数都可以构成函数的隐藏。之前我们介绍的都是多态的基本的使用方法。

2024-09-12 12:11:01 664

原创 C++当中的多态(一)

所谓的多态在我们的生活当中其实很常见。举一个简单的例子:当我们需要买票的时候有很多种不同的票可以供我们购买,如果你是学生就可以享受半价票的优惠,如果你是VIP用户就可以享受八五折的优惠,如果你是烈士家属就可以享受优先购票的权利.......那么像这种针对于同一个窗口,但是由不同的人,来进行相同的购票操作,最终得到不同的结果的现象就叫做多态。多态实际上就是不同继承关系的类对象,在调用同一个函数,做出了不同行为的现象。比如我们上面编写的代码当中学生类以及VIP类等都继承了购票窗口类。

2024-09-11 22:16:20 1024

原创 C++当中的继承(二)

每一次调用基类的构造函数的时候都会对我们 的静态成员变量进行++操作,这样不论是创建我们的基类对象还是创建我们的派生类对象都会进行统计,我们这个类型的对象个数也就被统计出来了。当我们产生该种继承方式的时候就会出现数据冗余和二义性的问题,因为我们会发现在类B和类C当中都继承了类A,所以我们类A当中的数据自然也就复制了一份到我们的类B和类C当中了,那么派生类D在继承类B和类C的时候又会将类B和类C当中的数据复制一份到我们的类D当中。所谓的虚继承就是专门应对我们菱形继承所带来的问题所引入的概念。

2024-09-10 18:38:43 974

原创 C++当中的继承

在C++当中继承是一个非常重要的语法。我们可以使用继承快速的进行代码的复用以及对代码进行扩展操作。首先我们来进行学习继承的基本语法。

2024-09-10 18:37:48 906

原创 模板相关知识的补充

我们之前没有产生类似的报错的原因是:我们之前仅仅是使用该模板参数创建了一个对象,对于该对象我们仅仅是调用了其中的成员函数,成员函数的使用方式和语法跟我们成员变量的语法已经内部类的使用语法不会产生冲突,(成员变量的使用语法跟内部类的使用语法产生了冲突)所以就没有出现上述的报错情况。还记得我们上一篇博客当中讲到的:仿函数吗?我们可以对于仿函数进行控制,使得我们得仿函数可以发挥类似于函数的作用。但是如果如果我们不小心传成了指针呢?我们会发现程序运行的结果出现了异常,我们期望的是可以输出12<15的结果。

2024-09-05 17:15:22 1125

原创 priority_queue和reverse_iterator的底层实现

对于priority_queue顾名思义是一个名叫优先级队列的类。但是仅仅通过这个优先级我们并不能判断其具体的用法以及功能。但是如果我们说到优先级队列的本质上应该是一个堆呢?我们的优先级队列实质上是使用堆进行实现的,其功能就是对我们插入的数据进行构建,构建成为一个堆的形式。堆顶的元素永远是数组数据当中最大或者最小的,因此我们可以通过和最后一个数据的交换就可以实现对数组的排序。那么我们就不难想到我们优先级队列应当拥有的函数接口:首先我们需要拥有一个数据的插入接口push,以及一个数据的删除接口pop。

2024-09-05 12:11:27 635

原创 栈和队列的学习以及实现+双端队列的底层原理

但是相信大家肯定会有一个疑惑:我记得我们在使用stack栈的时候不需要传两个参数呀?我们只需要传入一个参数不久可以了吗?我们仔细观察一下stack和queue的模板参数就会发现:在系统库实现的过程当中我们设置了一个默认的模板参数deque。这个默认参数的实现就使得我们不需要手动传入参数就可以正常使用stack。我们同样可以设置一个默认的模板参数。难道这个默认的模板参数只能选择deque吗?我们选择其他的数据容器行不行呢?我们测试一下会发现是完全可以的。

2024-09-01 19:05:57 859

原创 list类底层逻辑实现

list的底层逻辑是一个双向带头链表。那么list的底层其实就跟我们之前实现的带头双向链表相同,都是开辟一个一个单独的节点,最后再通过指针将各个单独的节点链接起来即可。我们来类比之前编写的双向带头链表实现具体的内容。

2024-08-31 20:21:14 1110

原创 list的使用及其相关知识点

作为数据容器之一的list和其他容器的使用上有很多相似的地方,比如都有大致相同的构造函数,大致相同的头插尾插,头删尾删函数。因此对于重复的内容我们就不在赘述,直接介绍关于list和其他数据结构容器不相同的使用方法。

2024-08-28 21:06:06 1318

原创 vector相关功能的底层实现

如果是经常编写C++代码的同学,相信大家肯定对于vector都不陌生。但是对于vector的底层逻辑大家真的熟悉吗?在本次的博客当中我们将会向大家介绍关于vector底层的逻辑,以及在实现底层逻辑需要注意的事项。查阅相关的文档我们会发现,和我们之前编写的string有所不同。vector采用的是三个指针的形式进行表示的vector内存的大小以及容量的。就像上图中所显示的那样,其中的start / finish / end_of_sotrage 才是vector类当中的私有变量。

2024-08-28 09:40:12 816

原创 使用递归形式以及迭代形式实现树的前中后序遍历

相信大家对于二叉树的遍历并不陌生,对于二叉树的递归遍历我们也可以信手拈来。但是如果让我们将二叉树修改成为非递归的形式呢?是不是有点疑惑了?那么本次博客我们就来梳理一下二叉树的非递归遍历。由于递归遍历二叉树的代码以及逻辑都很简单,所以我们直接给出代码的结果,之后直接进行输出结果的比较即可。我们手动构建的树的形式如下图所示。

2024-05-29 12:49:28 984

原创 程序员代码面试指南(二)

我们可以创建一个栈,向栈当中不断地压入数据,在加入数据之前,我们需要先判断栈是否为空,如果为空就将数组当中指定位置的值修改为INT_MAX,因为该位置可能是边界数据,那么左边就不存在大于该位置的值。假设右侧的孩子节点的数据更大,所以我们child2的父亲节点毫无疑问是parent了,但是对于child1来说,我们会向左侧找到一个大于child1的数据parent,也会向右侧找到一个大于child1的数据child2。这就需要我们证明左右可能产生的节点的情况了,即证明数组的一侧孩子的数量不可能超过1。

2024-05-18 17:18:33 695

原创 程序员代码面试指南题目解析(一)

优选《程序员代码面试指南》书中优秀的思路以及算法,主动删去了较为简单的部分,可以帮助我们更好的学习

2024-05-11 23:00:34 1170

原创 力扣刷题:四数相加Ⅱ

在官方题解当中我们可以学到一个解法:我们可以将四个数组分成为两个一组的形式,将一组当中的两个数组进行相加合并,将两个数组当中的元素进行完全匹配相加,合并之后就可以将两组新的数据进行匹配,之后就可以将题目的要求修改为两个数组查找指定的值。所以我们需要重新进行优化,我们可以提前对数组当中的数据进行处理,使用哈希表进行映射,哈希表的键为数组当中数据的值,哈希表的值为数组当中该值出现的次数。我们会发现这种算法的时间复杂度为O(N^2),其主要需要进行的操作就是数组的合并,以及之后的数据查找操作。

2024-05-06 16:17:30 586

原创 插入排序和归并排序算法的实现和优化

插入排序算法是专门对于数组进行排序的一种算法。可以将无序的数组转化成为有序的状态。可以说插入排序算法是我们排序算法当中最简单的算法之一。其主要进行的操作和我们打扑克当中抓拍的思路很相同。我们只需要保证我们最开始的数组为有序状态,拿到一个新的数据的时候就可以将该数据从最右边开始向左进行判断我们新数据想要插入的位置。如果小于我们最右边的数据就进行交换操作。直到第一次数据大于左侧的数据即可。实际过程如下图所示:但是我们可能有的同学会想:要是前面的元素不有序呢?这样不是使用起来很局限吗?

2024-04-16 18:02:51 643

原创 常用算法——双指针算法

所谓的双指针算法看似十分的神秘,但是实质上就是两个标志查找元素的变量。双指针既可以是我们平常最常说的指针(类似int *类型的数据),也可以是数组的下标。因为对于一个数组数据的查找,通过下标我们照样可以找到相应的数据。而我们最经常说到的算法当中的指针并不是平常所说的指针,而是类似于数组下标之类的,方便于查找对应的数据的值。而双指针算法就是通过两个“指针”方便我们查找对应的数据以达到对应要求的算法。

2024-04-14 13:37:02 1145

原创 leetcode刷题系列(一)

为了优化我们的程序,我们在这里向大家介绍一个方法:对于有序的二维数组我们可以将右上角的元素作为标记元素,将我们目标元素和他作比较,如果右上角的元素小于我们的目标元素就可以删除一行的元素,(右上角的元素是本行最大的元素)。如果右上角的元素大于我们的目标元素就可以删除一列的元素,(右上角的元素是本列最小的元素)。但是我们会发现我们数据的总检查的次数为1+2+...+(n-1)+n我们的时间复杂度还是O(N^2),我们所进行的效果很小,算法的时间复杂度还是属于N^2级别的,所以我们还需要思考其他的方法。

2024-04-14 13:35:30 1072

原创 类和对象练习:ClassDate

对于C++类的使用练习

2024-04-14 13:33:58 626

原创 蓝桥杯刷题

之后就是我们的递归的写法,本质上的思路和我们的暴力计算很像,也是将每一种牌看成从 0 - 4 五种情况。如果数字超过13同样直接返回,(需要注意的是我们在传参的时候由于第一次传参的值无法进行四次循环,进行四次循环的是传参的值加一,所以我们需要传入0作为参数,实质上表示牌的点数的数字为 1-13)如果是普通的情况就进行从0-4五次遍历,表示这一种牌总共可能会那几张牌。主要思路就是将每天的跑步数量泛化,也就是将每一天跑步的米数都看成1,等到符合一定的条件的时候将米数再加1,这样可以简化对题目程序的编写。

2023-11-15 12:54:00 532

原创 进程地址空间

所以我们的进程地址空间和页表当中的数据就会和我们进程当中的其他数据一样需要被带走,等到我们的进程再一次需要运行的时候再次被切换到CPU当中。这也是我们一个相同的地址当中可以保存两个不同的数据的原因,相同的只是我们虚拟出来的地址,真正存储数据的物理地址实质上还是不同的。在我们程序的编写过程当中,其实我们所有能够看到的地址都不是实际的物理地址,而是被我们创建出来的虚拟的地址。我们在上面说到过:进程地址空间是属于每个进程所独有的,每个进程在运行的时候都会创建一个属于自己的进程地址空间。

2023-10-29 10:47:03 198

原创 进程相关内容(三)

由于我们操作系统当中的进程有很多种,但是我们的数据资源有限。所以我们的进程在运行的时候需要区分一定的顺序,这样才不会造成进程方面的干扰。所以在我们的操作系统当中引入了进程优先级的概念。

2023-10-18 22:45:35 241

原创 进程相关介绍(二)

当我们的进程运行的时候有很多状态,因为我们的CPU资源是有限的,我们的进程必须有选择性的放入CPU上面才可以运行。因此我们的进程就存在了很多种进程状态,比如运行态,阻塞态,挂起态等等。在本次的博客当中我们就来详细介绍一下关于进程介绍以及进程优先级的相关知识。上述图片就是我们进程当中的许多种状态,由于归类的不同所属状态也不同。我们挑选其中的比较重要的三种状态进行讲解。

2023-10-16 12:28:57 205

原创 进程相关介绍(一)

一个进程实质上就是一个被执行的程序。操作系统会将这个程序使用PCB结构体保管起来,之后通过链表的形式将各个进程的PCB结构体和其相对应的代码数据管理起来。在Linux当中PCB结构体有很多种,最主要的是task_ struct。在task_ struct结构体当中存储着各种进程的的属性。例如:标示符,状态,优先级等等。为了更加清楚的认识进程相关的知识,我们将会依次介绍其中的几个主要的属性以及集中最主要的进程。

2023-10-10 21:46:51 230

原创 操作系统和进程相关的认识

在认识进行相关的知识之前我们需要先认识一下关于操作系统的相关的知识。据我们所知操作系统是位于软件和硬件之间的,可以协调软件和硬件之间的工具,那么我们的操作系统到底是怎么处理硬件与软件之间的关系呢?操作系统又是怎么与硬件链接起来的呢?那么我们就从硬件开始入手,一步步带大家认识一下操作系统的作用原理,以及其中进程的概念。

2023-10-06 16:51:45 156

原创 gdb的使用

在我们编写代码的过程当中我们肯定会遇到程序运行的结果不符合预期的情况,这个时候我们就需要通过调试代码找到错误,并进行修改。在平时的程序编写的时候我们使用的都是VS2019集成开发软件,其中已经封装了图形化界面的调试方案。可以很好的帮助我们进行代码的调试。但是在Linux系统当中,我们要想对代码进行调试就需要使用我们的调试工具,并通过特定的指令进行代码的调试以及运行。在本次的博客当中我们将对比在VS2019环境当中的代码调试步骤以及在Linux当中的代码调试步骤,帮助我们学习gdb代码调试工具。

2023-09-30 19:56:41 368

原创 Linux系统下git相关使用

git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。简单的说,也就是资源备份系统。相当于一个云端,我们可以向云端传输一个文件,便于我们的文件的管理以及修改。简单的举一个例子:学校里面的老师让写毕业设计,你兴高采烈的写完之后找到老师让老师看是否过关。可是老师并不满意,于是对你说,不行还得改。于是你就回去修改了一遍,修改完成之后又让老师看了一遍。可是老师又在吐槽,还没第一次写的好呢。于是又让你回去进行修改。之后你就又回去修改自己的毕业设计,于是便有了第三版。

2023-09-30 09:34:38 307

原创 进度条程序的编写

进度条代码的书写

2023-09-29 15:59:11 263

原创 makefile相关知识的讲解

makefile是一个文件,其中保存的是我们想要统一所进行的命令操作,例如我们编译代码生成可执行程序的时候所需要执行的 -E -S -c 等操作。(当然可以直接生成可执行程序,但是我们在这里为了模拟makefile的多指令执行操作而特意的分步进行)因为makefile起到管理命令的作用,所以我们再使用make执行之前必须先创建一个makefile文件,在这个文件当中编辑指定的命令。我们先来通过例子观察一下makefile的具体的使用方法,之后在进一步进行讲解。

2023-09-28 08:58:14 250

原创 sudo文件的配置以及gcc&g++工具的使用

这就需要和我们之前的头文件相关的知识联系起来了,我们知道的是在预编译的步骤里会将头文件当中的内容展开放到我们书写的代码当中,但是一个头文件那么多函数只会有800多行吗?我们的注释在预处理的步骤当中已经被去掉了。库文件分为动态库和静态库,在链接这个步骤当中我们会通过头文件当中的函数的声明以及链接找到指定的库文件,之后我们的程序才可以成功的实现函数的调用。在链接的时候我们提到了静态库和动态库,在那一部分我们只是简单的介绍了库文件的作用,那么接下来我们再来详细介绍一下什么是静态库和动态库,以及这两者的区别。

2023-09-25 09:23:52 1012

原创 yum和vim工具的使用

在本次的博客当中我们主要来认识一下yum和vim工具的使用,其中以vim工具的使用介绍为主。

2023-09-24 14:51:06 299

原创 对权限的理解和使用

在Linux当中我们经常会遇到命令执行不允许的情况,通常会产生如下的报错:我们想要读取一个文件,但是却无法执行。会显示Permission denied。这就是因为权限所造成的影响。权限分为两大类:每个用户所具有的权限,以及事物所具有的权限(多指文件的权限)。只要弄清了这两部分我们以上的现象就会了然于胸。

2023-09-20 16:49:26 563

原创 C++学习——vector类的使用

vector是C++中的部分内容,中文偶尔译作“容器”,但并。它是一个多功能的,能够操作多种数据结构和算法的和。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的,能够增加和压缩数据。实质上vector的作用等同于数据结构当中的顺序表。因为vector是使用模板实现的,所以我们可以通过传入指定的参数,进行存储各种类型的数据。

2023-09-09 16:57:12 365

原创 C++学习——string类的模拟实现

经过上一次的博客之后我们已经认识了string类,并且可以使用string类当中的相关的成员函数。为了巩固我们学习到的相关的知识,在本次的博客当中我们将自主实现一个string类来完成相应的功能。

2023-08-15 17:40:22 132

原创 C++学习——认识什么是STL以及string类的使用

在C++语言当中我们还引申加入了很多的额外的功能,比如我们现在需要进行学习的字符串string。大家可能会很好奇为什么会新加入一个字符串呢?我们C语言当中不是已经有过字符串了吗?我们再来详细的观察上面的代码:变量名ch前面的char表示的是ch的类型也就是字符类型,后面的 [ ] 表示的是我们代表一个数组,所以实质上在C语言当中的字符串实质上就是一个字符数组。并不是真正意义上的字符串。并且我们经常会遇到针对于字符串的修改等操作,所以在C++当中我们就专门定义了一个类,用于管理字符串相关的一系列的操作。

2023-08-07 07:25:31 140

原创 C++学习——模板

模板是在C++当中经过引入了函数的重载之后所诞生的一种新的功能。想要详细的了解模板的好处就需要从函数重载的例子开始说起。//根据函数重载的例子来了解模板的好处void swap(int& a, int& b) //交换函数1a = b;b = tmp;void swap(double& a, double& b) //函数重载2a = b;b = tmp;void swap(char& a, char& b) //函数重载3a = b;b = tmp;//写一个模板。

2023-08-03 21:57:18 308

原创 C++内存管理(动态内存开辟)

我们在C语言当中想要使用堆区的空间的时候就需要使用malloc函数进行手动的申请,但是我们在申请的时候需要手动进行计算,经过计算之后还需要进行判空操作,并且还不能进行任意值的初始化。这一切看起来在学习完C++当中的动态开辟之前显得很正常,但是在学习完C++当中的动态内存开辟之后我们就会感绝倒C语言的麻烦之处,接下来我们就来认识一下C++当中的动态内存开辟操作符,并将它和C语言当中的malloc函数进行对比吧。

2023-08-02 21:16:41 1183

原创 C++学习——类和对象(三)

同样的我们先使用函数体初始化不具有默认参数的成员变量:我们会发现编译器依旧会产生报错,之后我们再来使用初始化列表进行初始化:上面三种成员变量我们只可以使用初始化列表进行初始化,这也是初始化列表产生的意义。在我们正常的程序编写的过程当中,我们比较推荐使用初始化列表进行初始化我们对象的成员变量,这是因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使 用初始化列表初始化。所以为了减少我们的区分,我们可以直接使用初始化列表进行初始化操作。

2023-07-26 10:51:53 172 1

原创 C++学习——类和对象(二)

紧接着我们上一部分类和对象的讲解之后,我们再来学习一下类当中的几大特点,以及使用方法。

2023-07-19 12:14:13 272

空空如也

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

TA关注的人

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