自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 模板初阶(入门)

int main()// 类模板都是显示实例化// int// double//...delete pst;return 0;

2025-12-02 02:20:16 245

原创 类和对象(中)——日期类的实现&取地址运算符重载

这篇文章笔者先带领读者实现一下日期类,然后学习类和对象中的取地址运算符重载。

2025-10-29 23:19:22 128

原创 类和对象(中)——拷贝构造函数&赋值运算符重载

拷贝构造函数也是C++中新i出的函数,其具有很重要的作用,弥补了C语言中一些很坑的部分,学习难度也较大,希望读者认真学习。

2025-09-28 15:46:26 743

原创 类和对象(中)——构造函数和析构函数

注意到这里报错了,这是因为这样的操作并不是定义了一个对象func,而是声明了一个函数func,这个函数,所以这也说明了构造函数的一个需要注意的点:那就是不能用它来定义函数,因为编译器不能分辨是生成对象函数还是函数声明。如果类中没有申请资源时,析构函数可以不写,直接使⽤编译器⽣成的默认析构函数,如Date;构造函数是一种特殊的成员函数,不过构造函数的任务并不是开空间构造对象,而是将对象实例化和初始化,类似于Init函数,其实构造函数的本质就是替代这个函数的功能,其自动调用的特点直接完美替代了Init。

2025-09-25 20:49:43 597

原创 类和对象(上)

首先,我们要先了解类的概念,其实类比较类似于C语言的结构体,当然,肯定比其方便很多。class是定义类的关键字,Stack是类的名字。{}中是类的主体,注意类定义结束时后面的分号必须存在,而类体中的内容就是类的成员,类中既可以定义变量,又可以定义函数,而C语言中的结构体不能定义函数,只能另外封装。另外struct也可以定义类,由于C++对C的兼容,struct在C++中将其升级为了类。最后一个小点:我们默认了定义在类里面的成员函数默认为inline。

2025-09-24 00:17:03 766 1

原创 C++入门

参考 - C++ 参考C++参考 - cppreference.com下面笔者介绍C++中的一种极其重要的语法——引用。引用其实类似于C语言里的指针,当然二者有本质的区别:指针是所指向内容的地址,是有实际空间的,而引用没有,引用是单纯的别名,并没有单独的存储空间。// 引用:b和c是a的别名int& b = a;int& c = a;// 也可以给别名b取别名,d相当于还是a的别名int& d = b;++d;// 这里取地址我们看到是一样的。

2025-09-23 15:46:37 668 4

原创 计数排序&&排序性能测试&&排序算法总结

不过读者需要注意的是,不能直接用数据的值求range,因为会存在浪费空间的现象,比如最小值为100,难道要开辟100以上空间的数组吗,因此我们要用映射去理解,而且这样的话即便是负数元素也可以比较,最后再回去即可。首先,笔者在本文讲一种排序,计数排序,这种排序和我们之前学过的排序并不一样,因此笔者放在这里讲解一下,不过读者需要注意的是,这种排序其实是有实际意义的,但是的确比较冷门。,它通过统计每个元素出现的次数,再按顺序输出,从而实现排序。首先,我们还是需要认识一下计数排序:计数排序是一种。

2025-09-18 00:45:03 362 2

原创 归并排序递归与非递归实现

首先,读者要知道什么是归并排序,其实在之前的文章中,我们写过一道链表相关的算法题,是把两个链表合成的一道题,写那道题的时候,笔者教了读者分而治之的思想,所以归并排序就是这种分而治之的思想,给定一组数据,然后将其分开,然后把分开的每一段都变成有序即可。

2025-09-14 22:01:32 1445 1

原创 快速排序的优化算法&非递归法实现快排

首先,我们要明确目标,既然是为了用非递归替代递归,那就说明需要用一种数据结构模拟递归的实现,我们可以从递归实现来思考,递归无非是分割区间,然后再次分割区间,比如[0,9]被分成[0,4],[5,9]然后两个子区间再次分割,然后我们联想到之前的数据结构,不是栈就是队列,我们再思考一下二叉树遍历的逻辑,其实是深度优先的,不断往下走,然后不符合条件再向上返回,因此,其实栈才是符合条件的,因为栈满足后进先出,所以栈完全可以实现递归的模拟,右区间先入栈,然后左区间入栈,以此类推即可。

2025-09-12 21:42:08 1781 3

原创 交换排序——冒泡排序与快速排序

就是这样开始即可,然后左找大,右找小,先让R(right)出发,然后每个值和key对比,如果这个值比key小,那就停止,然后L(left)开动,和key继续比较,直到对应的值大于key时,停,此时right小于ker,left大于key,二者交换位置,这样就会让比key小的往左,比key大的往右,然后继续走,依旧这样进行,直接二者相遇,二者一定会相遇,后面笔者会再证明,遇到之后,把key和相遇位置交换,这样就保证了升序排序。今天,笔者带领大家学习交换排序,交换排序有两种,一种是冒泡排序,一种是快速排序。

2025-09-09 23:21:19 281

原创 选择排序与堆排序

这篇文章笔者带领读者学习选择排序,分为直接选择排序和堆排序,堆排序在笔者之前的文章有介绍,笔者不过多赘述,读者可自行查阅。比较简单,笔者不作过多赘述。

2025-09-07 17:25:19 240

原创 插入排序与希尔排序

希尔排序法又称缩小增量法,预处理是为了让其更接近有序,也就是说在接近有序的基础上再进行排序会让插入排序的效率优化很多,因此我们先思考什么是预处理:其实就是先分组,选一个值gap,然后从第一个值开始分组,每间隔gap的元素为一个组,然后对这个组里的元素进行插入排序,需要注意的是,这里gap的选择理论上是都可行的,但是经过计算,gap取3是最合适的,当然gap取1的时候就是正常的快速排序,gap越大,跳的越快,越无序。然后这种排序的时间复杂度比较麻烦,读者记住即可:O(N^1,3),感兴趣的读者可自行查阅。

2025-09-07 12:58:30 530

原创 二叉树结尾——销毁,层序遍历与判断完全二叉树

下面的问题就比较困难了,层序遍历这个二叉树,首先我们要知道什么是层序遍历,就是一层一层遍历,如何遍历并打印呢?这里需要用到之前的知识——队列,为什么呢?观察上面的代码,首先初始化,然后进行了一次入队操作,只要根结点不为0,那么就入队,不过需要注意的是,这里进入队列的不是结点,更不是结点对应的数值,应该是指向结点的指针,引起需要用&q,然后就是正常的操作了。

2025-09-03 18:17:18 182

原创 关于链式二叉树的几道OJ题目

其实这个问题在之前的文章中笔者提到过,递归实际上是栈帧问题,通俗理解就是每个副本都会有一个新的i,那些不用的副本中的i始终从1开始,这就会导致混乱,因此需要传入指针,可以理解为传入指针会让根本改变,因为地址找到的东西是固定的,相信到这读者都能理解笔者这么写的原因了。以笔者的习惯,还是先看题目给的函数,传入了两个指针。ok,这就是本文的最后一道题,这道题比较综合,不难理解,这道题的本质是先按照前序创一个二叉树,然后中序遍历,把遍历结果储存起来,其实这道题就是把之前讲过的东西结合在了一起,读者自行完成。

2025-08-23 22:16:54 763

原创 链式二叉树的剩余操作

第一眼看,其实并无什么问题,但是我们不妨想一想,这里的Int是否存在这样的问题:如果不用static修饰单单一个int,这样的话,每次调用函数时都会把size重新定义为0,也就无法造成叠加的效果,这是因为递归其实是在调用栈帧,所以笔者想到了加一个static让int变成静态区的变量,可是这样是不是就可以完美解决了呢?对于这个操作,我们自然想到的思路是遍历,每遍历一次就size++,最后返回size即可,在这个过程中,用到类似的递归方法,最后就实现了这个功能,那么具体如何在代码上实操呢?

2025-08-21 00:41:50 1580

原创 链式二叉树的基本操作——遍历

前序遍历:根节点,左子树,右子树。中序遍历和前序遍历的情况基本一致,并无不同,中序遍历结果:((N 3 N) 2 N )1 ((N 5 (N 7 N )))4 (N 6 N))本文笔者将带领读者一起学习链式二叉树的一些基本语法,至于更难一些的插入删除等,笔者将在后续C++更新后再次详细带领大家学习。下面我们只对这个二叉树进行讨论,首先进行遍历,二叉树的遍历有三次,分别是:前序遍历,中序遍历,后序遍历。中序遍历:左子树,根节点,右子树。后序遍历:左子树,右子树,根节点。

2025-08-16 21:52:25 457 2

原创 二叉树——堆及其实现

这个接口是用来实现堆的插入的,需要用到向上调整算法,故在其下面完成,这个接口实现其实并不难,很多都是老生常谈的问题,比如申请空间,断言,后面的就是真正意义上的堆的插入,首先先在最后一个位置插入x,然后将size++,最后一定要用向上调整算法,因为插入的东西不知道是否是孩子,如果不是,那就破坏了堆的结构,至于向上调整算法的参数一定要注意用size-1,因为此时size已经增加了,所以最后一个元素的下标仍然是size-1。再往下就是很平常的各种接口:定义,销毁,插入,删除,取顶部,判空。

2025-08-05 23:48:06 692

原创 循环队列的两种实现

这是第二个接口,旨在实现入队的操作,首先得判断一下队列不能满,然后就是把tail视作指针,把新值放在tail所指的位置,在让tail++,最后,如果tail已经到末尾了,那就需要回到0,也就是取模的操作,归根结底就是为了保证越界后绕回起点。这种方法中,我们首先了解循环队列的逻辑:循环队列就是基于FIFO的原则,队尾和队首形成一个循环,可以利用一块同样的空间,类比一下图书馆排队占座位即可。如上图,这是第一个接口,因为需要多用一个位置,所以就需要令K为k+1,*a就是数组的指针。

2025-07-24 19:43:10 311

原创 队列的实现

断言之后,先申请一块新节点,申请的时候要排除掉申请失败的情况,排除掉之后,新节点的下一个节点的指针是NULL,新节点对应的值就是x,不过这时需要讨论一下:如果尾指针是NULL,说明这个队列一个节点都没有,所以这种情况下首尾指针必须都指向newnode。如上图所示,定义了一个节点,这时,我们自然而然想到,实现队列操作的时候,需要对头尾进行操作,之前的学习中,我们知道应该用二级指针,进而改变头尾指针,当然,在这里我们用另一个方式——结构体Queue。出队列:进行删除操作的一端称为。的节点(最后一个元素)。

2025-07-23 14:48:13 261

原创 栈的知识和一道OJ题

首先,学习栈之前,我们需要知道栈是什么,栈就是一种特殊的线性表,这种结构只允许在一边增加,删除,这一边也被称作栈顶,栈的插入称作压栈,栈的删除称作出栈,这两种操作哦要从栈顶进行。如上图所示,首先定义一个新的容量,用三目操作符把为0 的情况也包含进去了,然后再定义一个新的指针,这个指针就是就是申请的内存空间,用一个临时变量存储。首先两个断言,top代表的是数组的长度,下一个元素的下标,所以取栈顶元素的时候直接用top-1即可。因为top代表的是长度,所以直接返回top即可。) → 必须配对最近放的 (

2025-07-22 01:00:02 377

原创 顺序表,链表OJ强化

首先,我们要知道,快慢指针这种算法一定是基于一个链表进行操作的,然后往往慢的和快的通过某种联系,让快指针或指向的下一个指针指向空的时候,slow指向的内容就是题目要求的内容,本题就是一道典型的快慢指针问题,因为倒数第k个如果遍历的话,也需要数k,所以直接让快指针先走k,然后等到快指针指向空即可。如上图所示,先判断的两个单链表的长度,如果二者尾节点都不一样,那么一定不相交,abs是求绝对值的函数,注意一定要让长的先把差的步数走一下,然后就是基本内容了。本文,笔者讲对顺序表和链表相关的算法题进行进一步的加深。

2025-07-21 00:20:05 310

原创 空间复杂度

注意看这道题 ,前一部分是申请了n个内存空间,所以空间复杂度是O(n),后一部分是循环,第一次分配n个,然后依次减一,最后加起来就是一个等差数列,所以对应的复杂度就是O(n^2),整体的复杂度就是O(n^2)。本文介绍空间复杂度。其实在实际算法中并不很看重空间复杂度。常见的空间复杂度:O(1),O(n),O(n^2)

2025-07-19 16:49:00 223

原创 时间复杂度相关知识

看的是大概的估算,大O的渐近表示法,CPU很快,上亿次,大O估算计算算法属于哪个量级,只看量级最大的部分,系数不用看,因为N无限大的时候,系数不重要。此题目中,数组元素有序,所以a,b两个数可以分别从开始和结尾处开始搜,根据首尾元素的和是否大于sum,决定搜索的移动,整个数组被搜索一遍,就可以得到结果,所以最好时间复杂度为n。这道题是一个易错题,首先如果进行递推公式的迭代,那么容易算出来就是一个等差数列,但是,问题是,这道题问的是第N项的时间复杂度,所以只用考虑第n项的时候,也就是O(n)。

2025-07-19 14:11:04 361

原创 双链表相关知识

在说双链表之前,先介绍一下链表的分类:链表分为带头不带头,带头指的是链表中有哨兵位的节点,该哨兵位即为头节点。然后还分为单向和双向,顾名思义,只能从一个方向遍历称作单向链表,能从两个方向遍历称作双向链表。单链表就是单向不循环链表,链表有8种,但是常用的只有带头双向循环链表,也就是双链表。双链表需要两个指针,一个是向前,一个是向后,还需要连接起来,构成循环。双链表的节点包括:数据+指向下一个节点的指针+指向前一个节点的指针。不过需要注意的是,最下面那两行代码不能交换位置,因为如果交换了,就找不到头节点了。

2025-07-15 15:35:16 385 1

原创 关于链表的一些算法题

定义新链表需要定义他的头节点和尾节点,并让他们初始为NULL。题意不难理解,首先最简单的思路还是对原链表遍历,然后创建一个新链表,对应赋值,不过这种算法比较基础,而且比较慢,下面介绍三指针法:首先先判空,如果head为空,那就直接返回head,反转后也是空。不为空时就用三指针法,n2代表头指针,n1是一个空指针,n3时n2的next指针,然后开始while循环,循环什么时候终止先不用看,先进行循环体,局部改变,先让n2的next指针指向n1,再让n1指向n2,n2指向n3,n3指向他的next。

2025-07-14 11:37:16 298 1

原创 单链表的相关内容

节点的物理结构不是连续的,所以需要指针来连接起来,节点有两个部分,第一个部分存储的是变量,第二个部分就是一个地址(也就是指针),而每一个节点存储的指针其实就是下一个节点的地址,这样就能通过前面的节点找到后面的节点了。首先需要申请一块内存,只不过链表的每个节点是独立的(物理上),所以每个都需要用malloc申请,不过记得强转,节点有两个值,所以应该在定义一下存储的数据,下面在利用指针把这些节点联系起来,注意最后一个节点指向空,记得定义一下指向第一个节点的指针。

2025-07-12 00:43:32 487 1

原创 数据结构—顺序表

其他不做过多赘述,最难的一点其实是前置声明,在Contact.h这个头文件中,由于通讯录的底层就是封装好的顺序表,首先需要在这个头文件中把结构体定义一下,结构体就是原来顺序表的一个整型元素,然后再把顺序表改名字变成通讯录,其中需要注意SeqList必须前置声明,不能直接调用对应的头文件,因为并包情况必报错,声明之后,在重新定义为Contact即可。5.尾插,尾删,头插,头删:四个操作没什么区别,本质都是指针的运用,在进行操作之前,首先需要断言确保有意义,然后需要检查内存容量。通常申请空间都申请原来的2倍。

2025-07-08 18:46:11 314

原创 深入理解指针

在上文呢,我们介绍了指针数组,那其实是数组,现在呢,我们就来介绍一下数组指针,数组指针呢本质上就是指针,我们学过了字符指针,整形指针,浮点型指针,这些指针的作用都是指向,只不过指向的东西不一样而已,数组其实也是一个类型,所以数组指针自然存在的。顾名思义,二级指针就是指针的指针,也就是二级指针指向指针,指针在指向一个东西,其实本质就是一个指针变量也有地址,他也指向另一个地址,因为二级指针和指针是一样的,无非就是套了一层一样的,二级指针的解引用找到的是指针。这样就是assert的使用。

2025-06-12 16:43:15 451

空空如也

空空如也

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

TA关注的人

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