- 博客(27)
- 收藏
- 关注
原创 类和对象 —— 多态
多态是⼀个继承关系的下的类对象,去调⽤同⼀函数,产⽣了不同的⾏为。⽐如Student继承了Person。Person对象买票全价,Student对象优惠买票。那什么是虚函数呢?在类成员函数前加关键字virtual,该成员函数就称为虚函数,注意,非类成员函数不能加virtual修饰。public:virtual void BuyTicket() { cout << "买票-全价" << endl;
2024-09-16 19:11:23
740
原创 找到字符串中所有字母异位词
第二步,创建left和right指针遍历s字符串,(left和right之间为待判断的子数组)当子数组的长度小于p时,将right指向的元素存入第二个哈希表hash2,right++;当子数组的长度大于p时,删去left指向的元素,left++;当子数组的长度等于p时,进行比对,判断是否为异位词,之后right++重复以上过程。因此可以选用创建两个哈希表的方法,将字符串的字母分别进行储存,再进行比对,如果两个哈希表一样,说明两个字符串就是异位词。指由相同字母重排列形成的字符串(包括相同的字符串)。
2024-09-05 15:36:28
367
原创 将 x 减到 0 的最小操作数
给你一个整数数组nums和一个整数x。每一次操作时,你应当移除数组nums最左边或最右边的元素,然后从x中减去该元素的值。请注意,需要修改数组以供接下来的操作使用。如果可以将x恰好减到0,返回最小操作数;否则,返回-1。
2024-09-05 13:19:39
751
原创 string类的实现
在C++的string库中,有许多关于string类的成员函数,极大方便了我们进行相关的操作,在这里我们尝试将string类中冗余的接口去掉,实现自己的string类。
2024-07-31 12:27:11
623
原创 C++ — 模板浅谈
swap(交换)函数,在排序等应用上存在广泛的用途,但是每次我们调用swap函数时,如果传的参数类型不一样,就要重载其他swap函数接收新的类型参数。这是因为之前的模板T只对Stack的类域有用,当出了这个类进行Push函数的定义时,编译器就认不出T是啥了,同时需要注意的是,模板不支持声明和定义的分开,这也就意味着我们不能在.h文件中进行声明,在.cpp文件中进行定义。而这种时候,我们有两种办法,第一是强制类型转换,即Add(a1,(int)d1),第二种就是显式实例化。类型的函数以供调用。
2024-07-23 21:01:23
751
原创 运算符重载
在C++的类和对象中,如果我们要对类类型的对象使用运算符,C++语言允许我们通过运算符重载的方式指定新的含义。同时,对类类型对象使用运算符时,必须调用对应的运算符重载,否则编译会报错。
2024-07-21 19:27:55
977
原创 构造函数与析构函数
析构函数与构造函数功能相反,析构函数不是完成对对象本⾝的销毁,⽐如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会⾃动调⽤析构函数,完成对象中资源的清理释放⼯作。构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象(我们常使⽤的局部对象是栈帧创建时,空间就开好了),⽽是对象实例化时。还需要注意的是我们显⽰写析构函数,对于⾃定义类型成员也会调⽤他的析构,也就是说⾃定义类型成员⽆论什么情况都会⾃动调⽤析构函数。
2024-07-17 20:45:15
318
原创 C++ — 引用浅谈
在上边的程序中,b为a的引用,能够看出,b和a的地址是相同的,这就代表编译器没有开辟出额外空间分配给b,引用的规则就是 类型& 引用别名 = 引用对象。从上图可以看出,在执行完b = d后,虽然a,b,c的值同步变为了30,但是a,b,c的地址却并没有变成d的地址,也就是说这个语句仅仅只是执行了赋值操作,没有真正地让b成为d的引用。在这段程序中,我们返回count的别名,但是当fun函数执行完毕后,该函数的栈帧销毁,而此时,ret的结果仍然是未定义的,系统清理完栈帧后置为随机值,此时ret也就是随机值。
2024-07-14 19:28:17
659
原创 C++ — 命名空间
C++引入了namespace关键字。想要解决这个问题,我们直接使用namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。如上图,此时再使用rand就没有任何问题了。namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下⾯的rand不在冲突了。C++中域有函数局部域,全局域,命名空间域,类域;
2024-07-12 19:10:05
307
原创 快速排序的实现
快速排序是Hoare于1962。拿这张图进行举例,第一步:R先向左走,找比key指向的值(即为6)小的值,找到5,R停下。第二步:L再向右走,找比6大的值,找到7,L停下。第三步:交换L与R所指向的值。之后重复上面三步,直到L与R相遇。最后,交换L指向的值与key指向的值。最后交换的结果就如上图所示,此时我们发现,在数字6左边的数字全都比6小,右边的数字全部比6大,这就表明数字6已经排好了位置。
2024-07-12 10:46:47
1163
原创 二叉树的实现
二叉树一般可以用两种结构存储,一种是顺序表,另一种是链表,一般来说,如果是完全二叉树可以采用顺序表储存的方式,但如果不是完全二叉树,就会造成空间的浪费。因此,我们采用二叉树的链式储存结构。这里介绍二叉链。
2024-07-09 10:47:30
390
原创 top-k问题
方法是先在所有的数据中选前k个数据构建一个小堆,之后遍历所有数据,并一一与堆顶元素相比较,如果比堆顶元素大(小),就将堆顶元素换为该元素,并向下调整。等所有数据遍历完以后,这个小堆的元素就是我们要找的最大(小)的元素。在拥有足够内存空间的情况下,最简单的办法就是创建一个足够容纳所有数据的大堆,然后取堆顶并删除,重复k次操作之后就得到了想要的数据。K个最大的元素或者最小的元素,一般情况下N远远大于K。首先,我们创建一个data的文件夹,并在其中存储10000个数据。强、富豪榜、游戏中前。
2024-07-03 09:59:38
193
原创 数据结构——堆
一、堆的概念数据结构中的堆通常指的是一种二叉树,利用顺序结构的数组存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。一、堆的概念堆总是一棵完全二叉树,如果子节点的值总是大于等于父节点,则称为小堆;反之则称为大堆。
2024-07-03 09:42:23
375
原创 树与二叉树
树是一种非线性的数据结构。它是由nn>=0)个有限结点组成一个具有层次关系的集合。。有一个,根结点没有前驱结点。除根结点外,,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。需要注意的是,在一棵树中,子树之间不能有交集。
2024-07-02 15:55:43
867
原创 用栈实现队列
设置两个栈,一个名为pushst,专门用来将数据入栈;另一个叫popst,专门用来删除数据。请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(
2024-06-28 17:43:42
268
原创 设计循环队列
设计你的循环队列实现。循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。: 构造器,设置队列长度为 k。Front: 从队首获取元素。如果队列为空,返回 -1。Rear: 获取队尾元素。如果队列为空,返回 -1。
2024-06-26 16:05:55
268
原创 C语言用队列实现栈
在将元素压入栈顶时,哪个队列不为空就压入哪个队列,之后元素出栈时,将非空队列的前size-1个元素提取出来,放入原本的空队列,再将剩下的一个元素返回,并移除该元素。请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(
2024-06-26 15:30:59
228
原创 数据结构—队列
一、概念:一、概念:队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出入队列:进行插入操作的一端称为出队列:进行删除操作的一端称为队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
2024-06-26 15:19:05
408
原创 数据结构—栈
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。栈中的数据元素遵守后进先出LIFO)的原则。压栈:栈的插入操作叫做进栈压栈入栈,。出栈:栈的删除操作叫做出栈。。
2024-06-23 19:11:50
374
原创 随机链表的复制
指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。1、在原链表的每个节点后插入一个节点,其val值和next指向的地址与前一个节点相同。节点组成,其中每个新节点的值都设为其对应的原节点的值。题解:这道题考察的是对含有随机节点的链表的复制。的链表,每个节点包含一个额外增加的随机指针。,该指针可以指向链表中的任何节点或空节点。3、抽出插入的节点并合并成一个新的链表。那么在复制链表中对应的两个节点。例如,如果原链表中有。
2024-06-22 19:24:43
309
原创 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
3、将头结点与逆置链表的val值相比较,知道其中有一个为空,如果val值不一样,返回false。2、逆置中间节点后的链表,并返回一个新链表的头结点。要判断一个链表是否为回文链表,我们采用如下方法。1、首先利用款慢指针找到中间节点。
2024-06-21 20:04:32
339
原创 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
那该如何找到相交的起始节点呢?当我们判断出这两个链表县相交时,只要让长的链表先走比短链表长的部分,然后长短链表一起走,直到两链表相等,再任意返回其中一个。首先是第一问,如何判断相交?其实很简单,只要将A链表和B链表各自走到自己的尾节点,判断两个链表的尾节点是否一致,就可以判断出两个链表是否相交。这个题目分为两问,第一问是这两个链表是否相交,第二问是如果相交,返回相交的起始节点。
2024-06-21 19:50:32
251
原创 时间复杂度
在上图中,我们可以清晰地认识到,由于cpu每秒能够执行的语句非常多,所以当N比较小的时候,计算机执行的时间非常短,这个时候谈论最高阶项后面的项没有多大意义,而当N比较大时,后面的项对最高阶项的影响所以我们在考虑时间复杂度时,也一般只考虑最高阶项。同时我们需要注意,在实际中我们一般关注算法最坏的运行情况,就比如查找数组中的某个数,运气好可能第一次就找到了。在这个代码中,++count运行了M+N次,所以O(N)= M+N。在这段代码中,程序运行了2^N次,所以时间复杂度为O(2^N)
2024-06-20 20:40:33
376
1
原创 链表带环问题与第一个环节点
快慢指针设置两个指针,一个名为fast,一个名为slow。两个指针开始指向链表头结点head。fast一次走两步,slow一次走一步。当fast进入环后,由于带环链表的next不指向空节点,fast指针一直在环内循环。当slow也进入环后,fast指针和slow指针也在环内循环,当fast指针和slow指针在环内能够相遇时,表明该链表带环。
2024-04-30 18:47:08
500
1
原创 文件的操作
fgetc函数只有一个参数,指向标识输入流的文件对象的指针。当文件读取到末尾或者发生读取错误时,该函数返回EOF。该函数用于输入字符,适用于所有输入流。
2024-03-27 21:09:19
677
1
原创 扫雷游戏的运行
一、扫雷游戏的规则:(1)随机打开一个格子,方格被打开并显示一个数字。(2)数字表示在打开方格的周围八个方格中有几个“雷”。(3)挖到了雷则结束游戏。现在以9*9的棋盘,随机存放10个雷为例。二、扫雷游戏的分析:(1)扫雷游戏首先要在棋盘上存放十个雷。因此我们想到创建一个9*9的数组来存放雷的信息,我们用‘1’来代替雷,用‘0’表示没有雷。(2)目前十个雷已经存放完成。但是假设我们排查了(8,0)位置,在访问周围八个方格的时候,会发现下面的三个方格越界。
2024-01-13 15:10:41
3496
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅