自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++入门基础

①定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量,函数,类型等。②anmespace本质是定义出一个域,这个域跟全局域各自独立,不同的域可以定义同名变量。int data;该代码就是命名空间的定义。我们可以看到在前两个打印中,在没有限定命名空间时,我们只能打印rand的地址,当我们限定了命名空间cc时,我们就可以打印出命名空间中rand的值。

2025-02-26 12:29:28 839

原创 二叉树与堆讲解

二叉树和堆的初阶内容

2024-10-17 22:31:33 1697 1

原创 二叉树——二叉树的遍历

在该函数中,首先我们需要判断在数组中该下标所指的元素是否为#,若为#号,则返回空,并且将下标+1.若不是#号,那么我们需要创建一个大小为BTNode大小的节点,并将该下标指向的数组元素填入。然后根据递归的知识,以该节点为这棵子树的根节点,接着向下调用CreatNode()函数。由题目可知,这道题一共分为两个部分,一是根据所给的字符串以前序遍历的方式创建一个二叉树,而是根据创建的二叉树以中序遍历的方式输出。然后根据我们之前所学的中序遍历的知识将刚才创建的二叉树中的节点输出,这里就不过多赘述。

2024-10-17 19:22:00 339

原创 二叉树——另一棵树的子树

由题可知,这道题可以拆分为,访问以每一个节点为根节点的子树,并判断该子树与subRoot是否相同,只要有一棵子树相同就返回true。那么通过这个我们可以知道这个需要应用到我们之前做的判断两个子树是否相同的思想,再结合访问每一个子树就可以访问了。由于应用递归的思想,所以最后的返回值应当用所有判断子树是否相同的值做逻辑或运算,只要有一个为真就全为真。然后我们首先判断每一棵树的子树的根节点与subRoot的根节点是否相同,若相同则判断两棵子树是否相同;若不相同则继续向下判断下一棵子树。

2024-10-16 20:42:38 459

原创 二叉树——二叉树的前中后序遍历

第一次调用preOrder()函数时,i=0,将1存放到数组下标为0的位置,i++,i=1。若此时继续调用preOrder()函数,传递的i值为1,那么存放数据4时将会存放到数组下标为1的位置,就会将2覆盖。在函数中首先我们应当判断该二叉树是否为空树,若为空树则直接返回,若不为空树,则先将该节点的数据存放在数组内,并将下标++。创建数组之后,由于我们是需要将二叉树存放在数组内,所以我们也应当将数组下标也一并传过去,所以我们调用preOrder()函数来将数据存放在数组内。提交过后我们会发现是错误的。

2024-10-16 19:50:44 498

原创 二叉树——对称二叉树

这道题的思想与之前的相同的树题目类似。区别就在于这道题比较的是镜面对称,所以在比较对象上面需要留意。大家可以自行尝试一下哦~

2024-10-16 18:57:32 339

原创 二叉树——相同的树

还是应用递归的思想,将这个问题拆分为三个部分,第一:当两棵树均为空树,或者访问到最后的子树时均为空树时,则返回true。第二:当两棵树中其中一棵树为空树,另一棵树不是空树,证明两棵树不相同,则返回false。第三:我们可以将这个问题思考成首先比较这两棵树的根节点,根节点相同再比较这两个根节点的左子树的根节点,左子树比较完毕后再开始比较右子树,依次递归。若节点不同则返回false,若相同则继续递归。到最后返回各节点的逻辑与值。若其中有一个节点不同则返回值就是false。感兴趣的可以自行尝试一下哦~

2024-10-16 16:39:13 173

原创 二叉树——单值二叉树

应用递归的思想,将问题拆分为各个小问题。首先,当为空树时返回true。然后,当该节点的左或右子节点存在且其左或右子节点不等于该节点就返回false。最后返回左右树的返回值的并且,即可。看到题目很容易想到的就是遍历二叉树,用根节点的数进行比较,但是,这么操作需要应用全局变量或局部静态变量等,就会很麻烦。所以我们还是应用递归的思想。

2024-10-16 16:16:34 155

原创 栈和队列——用栈实现队列

完整代码如下//////静态的栈//{//};//动态的栈int top;}ST;//栈的初始化//栈的销毁//栈的进栈//栈的出栈//栈的取栈顶数据//栈的判空//栈的获取栈的个数//栈的初始化//top指向栈顶的下一个节点//top指向栈顶//栈的销毁//栈的进栈//扩容");exit(1);pst->top++;//栈的出栈pst->top--;//栈的取栈顶数据//栈的判空。

2024-09-04 21:50:00 424

原创 栈和队列——设计循环队列

与上面的向循环队列插入元素一样,我们借助取余的方法,让tail-1再加k+1,再对k+1进行取余,这样,对小于k+1的数没有任何影响,且当tail=0时,可以让tail成功的循环回去,访问到队尾元素。如果还有空位,我们直接将元素赋值给tail,再++tail。=head,所以我们就需要借助取余符号,我们将所有tail+1都对k+1进行取余,当tail+1小于k+1时对于结果并没有影响,但是,当tail+1=5时,我们就可以应用取余的方法使tail+1=head,也就是完成了题目中要求的循环。

2024-09-04 19:17:47 1148

原创 栈和队列——用队列实现栈

整道题的基本思路与代码就讲解完毕了,下面附上本题的完整代码,如果大家感兴趣的话可以自行尝试哦~}QNode;int size;}Queue;//队列的初始化//队列的插入//队列的删除//统计队列内的数据个数//获取队列的头数据//获取队列的尾数据//队列的判空//队列的销毁//队列的初始化assert(pq);//队列的插入assert(pq);exit(1);//队列的删除。

2024-09-01 22:47:52 348

原创 栈和队列讲解(二)

队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点,即:先进队列的先出来,后进队列的后出来。我们称进行插入操作的一端为队尾,进行删除操作的一段=端为队头。在结构上,队列与平时餐厅的叫号系统相似。当餐厅需要排队时,我们通常会进行排号,先排队的号,会被先叫,后排队的号会被后叫。

2024-09-01 19:15:28 439

原创 栈和队列——有效的括号

在这道题中给出一个字符串包含三种不同的括号,需要判断这三个括号是否能相互匹配。因为方向需要保证不出错,所以我们可以想到如果指向字符的指针为左括号时,可以将它拿出,与下一个字符进行匹配若能匹配则继续匹配,如果不能匹配则返回false。那么将左括号拿出要存放在哪里呢,我们可能会想到创建一个字符去存储,但是若字符串中只含有一个半括号或左括号数目大于右括号时我们将无法判断。所以我们可以应用栈的知识,将左括号存储在栈内,若下一个是右括号则与栈的头元素进行配对,若能配对,则继续,若不能则返回false。

2024-08-30 22:41:01 376

原创 栈和队列讲解(一)

栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的元素遵守后进先出的原则,即后进去的先出来,可以将其理解为弹夹,后塞进去的子弹会被先打出来。进栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈,出数据也在栈顶。

2024-08-30 21:21:53 684

原创 单链表——随机链表的复制

深拷贝,就是将原链表彻底的拷贝,当我们观察这个链表时我们会发现,val与next都比较好拷贝,难点就是在random的拷贝,因为我们需要知被拷贝的节点的random指向的是哪个,所以我们很容易想到的方法就是从头遍历链表,再挨个进行拷贝,但是这样的话,我们的代码实现的时间复杂度为O(N^2),效率低下,所以我们不采用这个方法。第二种方法就是,我们可以在原链表中的每个节点后面增加一个节点,用来拷贝原节点的信息,这样我们通过原节点就可以很轻松的找出各个节点的random了。我们现在来实现一下这个方法。

2024-08-29 22:37:32 747

原创 单链表——环形链表II

根据第一道环形链表的题目我们可以得知快慢指针相交的节点,但是如果想要知道进入环形链表的第一个节点,我们就还需要定义一个指针从链表的头节点开始,与相交的节点同时行走,当两个节点重合时重合的那个节点就是环形链表的第一个节点。则快指针fast走的路程为L+x*C+N,慢指针slow走的路程为L+N,因为快指针走的路程为慢指针走的路程的二倍,所以我们可以得出等式2(L+N)=L+x*C+N,整理后可得L=x*C-N---->L=(x-1)*C+C-N。所以我们可以来实现一下这个想法。大家感兴趣的可以自行尝试哦~

2024-08-29 20:36:52 407

原创 单链表——环形链表

想要判断该链表是否为环形链表,就需要应用两个指针,如果两个指针所指向的节点相同,那么该链表就是环形链表。反之,若一个指针指向为NULL则证明该链表不是环形链表。所以这道题目的基本思想还是快慢指针,我们应用快慢指针以及追及问题的思想来实现这道题。大家感兴趣的可以自行尝试一下哦~

2024-08-29 17:19:39 168

原创 单链表——相交链表

我们可以先遍历两个链表。计算出两个链表的长度分别为多少,假设A链表的长度为N,B链表的长度为M,A链表比B链表短,则可以计算出AB链表相差M-N个节点。由此可知,这个方法的时间复杂度为O(max(M,N))。我们可以定义两个指针分别指向链表的头部,遍历链表A使A的每一个节点都与B的每一个节点比较,若地址相等,则返回指向A链表的指针,若不想等则将A指向A的下一个节点。这样可以得知,假设A链表的长度为N,B链表的长度为M,则该想法的时间复杂度为O(M*N),可知,该想法效率较低。大家感兴趣的可以自行尝试哦~

2024-08-28 23:06:54 311

原创 复杂度——链表的回文结构

首先我们先来看一下这个题目的限制条件,它规定了时间复杂度与空间复杂度,这就证明,我们的链表只能够遍历一遍,所以就不能够应用将链表后方的重复部分存储到数组内再进行比较的方法了。所以根据我们之前做过的单链表中的题目我们可以想到这个方法:我们可以先应用快慢指针找到单链表的中间节点,再将后面的节点全部逆置,再比较前面部分与后面部分的节点数据是否相同,如果相同则返回true,如果不同则返回false。那么我们现在来实现一下这个方法。大家感兴趣的可以自行尝试一下哦~

2024-08-28 21:55:48 208

原创 复杂度——返回倒数第k个节点

这道题的基本思想还是使用快慢指针。我们可以让快指针与慢指针之间相差k个节点。那么我们现在来实现一下这个方法。那么这串代码的时间复杂度为O(N),空间复杂度也为O(N)。感兴趣的可以自行尝试哦~

2024-08-28 20:56:20 247

原创 复杂度讲解

1.用常数1取代运行时间中的所有加法常数。2.在修改后的运行次数函数中,只保留最高阶项。3.如果最高阶存在且不是1,则除与这个项目相乘的常数,得到的结果就是大O阶。另外,有些算法的时间存在最好,平均和最坏情况:最坏情况:任意输入规模的最大运行次数(上界)平均情况:任意输入规模的期望运行次数最好情况:任意输入规模的最小运行次数(下界)例如:在一个长度为N的数组中搜索一个数据X最坏情况:N次找到最好情况:1次找到平均情况:N/2次找到在实际中。

2024-08-28 20:44:46 1128

原创 复杂度——轮转数组

那么我们现在算一下他的时间复杂度。最容易想到的就是当我们的k值等于numsSize的整数倍的时候,整个数组是不用变化的,这时候就是时间复杂度的最好情况。当我们的k等于numsSize-1的时候,时间复杂度是最坏的情况,这时,我们数组轮换一次所需要的时间复杂度为N-1,那么轮换N-1次所得出的时间复杂度的函数就是F(N)=(N-1)*(N-1),所以,时间复杂度O(N)=N^2。那么我们现在可以来实现一下这个方法。根据图示,我们可以知道,我们整个代码写下来的时间复杂度O(N)=N。那么我们现在来实现一下。

2024-08-25 10:05:38 392

原创 复杂度——消失的数字

我们可以先将数组nums排序,再从头遍历,若下一个数字不等于该数字+1,则下一个数字就是消失的数字。但是对于排序,若应用冒泡排序则时间复杂度为O(N^2),若应用qsort进行排序,则时间复杂度为O(N*logN)。我们可以先将nums数组中的数与0进行异或,再与0—N的数字进行异或,这样就只有消失的那个数字只被异或了一次,那么所得的值就是消失的那个数字。我们可以对0—N先进行求和,再将求和的数依次减去数组中的数,最后所得的数就是数组中缺少的数字。但是这种方法有弊端,就是当N过于大时会有溢出风险。

2024-08-22 19:08:54 235 1

原创 双向链表专题

想要打印双向链表,我们就需要应用while循环,在新建一个指针pcur,由于哨兵位节点的数据是无效的不需要打印,所以我们可以让pcur指针指向phead->next,循环的结束条件就是当pcur走到phead的时候,就可以跳出循环了。答案是传一级指针就足够了,因为哨兵位节点是不能被删除的,节点的地址也是不能被更改的,所以在传参时,只需要传一级指针就足够了。头插的思想与尾插相似,但是需要注意的是,头插指的是在哨兵位节点后面插入,也就是在第一个有效节点之前插入,即phead->next。再将pos节点释放掉。

2024-08-21 23:12:10 1077

原创 单链表——分割链表

第一个方法,我们可以在原链表上进行更改,当我们遇到大于等于x的数的时候,我们可以将该节点尾插到原链表中。若节点小于x则不做改动,继续向后比较。我们可以创建两个链表,大链表和小链表,大链表用来存储大于等于x的节点,小链表用来存储小于x的节点,最后再将两个节点连接在一起。我们可以新建一个链表,遍历原链表,若节点大于等于x则在新链表中尾插,若节点小于x则在新链表中头插。大家感兴趣的可以自行尝试哦。

2024-08-20 23:47:26 374

原创 单链表——环形链表的约瑟夫问题

我们可以先定义两个指针,一个指针指向环形链表的头节点,一个指针指向环形链表的头结点的上一个节点,然后开始计数,每当计数到规定数字时,就将该节点销毁,然后接着进行计数,直到只剩下一个节点,那么循环结束的条件就是,当指针的next指针与自身相同时循环就可以结束了。根据题意我们可以得出这道题可以应用环形链表的方法来解答。环形链表,顾名思义就是把单链表的头尾连接形成一个环形的链表来解题。那么,基本思想有了,具体的思路是什么呢?那么我们开始实现一下这个方法。感兴趣的可以尝试一下哦。

2024-08-20 21:31:23 237

原创 单链表——合并两个有序链表

这个题目的思路很容易就能想出来,我们可以创建一个新链表,然后用两个指针遍历两个链表,将小的节点尾插到新节点中。而循环的结束条件就是两个指针的任意一个走到空。在循环结束后,两个链表肯定其中一个走到结尾,而另一个没有走到结尾,所以我们需要在循环结束后,将没有走到结尾的链表尾插到新链表中。当我们运行后会发现,当list1或list2为空链表时不成立。所以在遍历链表之前我们需要先判断list1与list2是否为空链表。若list1为空链表则直接返回list2,若list2为空链表则直接返回list1。

2024-08-20 17:53:30 501

原创 单链表——链表的中间节点

通过这道题可以引出一个十分重要的算法解题思路——快慢指针。顾名思义,快慢指针就是有两个指针,一个指针走的快,一个指针走的慢。slow指针每走一次,fast指针走两次,这样就可以得出规律2slow=fast。当有奇数个节点时,循环的结束条件是fast->next指针为空指针;当有偶数个节点时,循环的结束条件是fast。当链表中有偶数个节点时,fast指针最后一次会走到空,空指针不能进行解引用操作。那么对于这道题,还有一个问题,能否将while循环的结束条件改为(fast->next&&fast)呢?

2024-08-20 17:04:59 261

原创 单链表——反转链表

方法二比较难以理解,但是十分简便。我们建立设置三个指针n1,n2,n3。n2指向链表的头节点,n3指向链表头节点的下一个节点。我们首先将n2指向n1,再将n1挪到n2,n2挪到n3,将n3挪到下一个节点。再将n2指向n1,将n1挪到n2,n2挪到n3,将n3挪到下一个节点。当n2为空时循环结束,下面来实现一下这个思路。首先,我们先来看一下这道题,很容易想出来的一种思路是新建一个链表,创建两个指针,应用头插的思想来实现这道题。那么我们来实现一下。感兴趣的可以自行尝试一下。

2024-08-19 20:02:13 256

原创 单链表——移除链表元素

除了直接在原链表上进行数据的改动,我们还可以新建一个链表,用来存放不等于val的节点。那么思路是这样的,我们使用一个指针遍历链表,当节点数据不等于val时,就将该节点存放在新的链表中。那么我们现在来实现一下这个思路。首先,我们先读一下这道题,可以了解到,就是应用基本的链表删除节点的方法,应用while循环遍历链表,遇到与val相同的节点则直接删除。我们现在来直接实现一下这个思路。这个题目就讲解完毕啦,大家感兴趣的可以自行去力扣解题哦。PS:对于单链表不熟悉的可以先去数据结构专题看一下。

2024-08-18 21:24:06 434

原创 单链表专题

针对顺序表,我们会发现顺序表会有一些问题,比如中间/头部插入效率低下,增容降低运行效率,增容造成空间浪费等,为了解决这些问题,可以应用单链表来解决。

2024-08-18 14:52:23 779

原创 顺序表——合并两个有序数组

首先,我们来看一下题目。

2024-08-04 19:02:53 429

原创 顺序表——移除元素

首先我们来看一下这道题由题目可知,我们很快的就能想出一种较为简易的解法。

2024-08-02 13:30:26 369

原创 顺序表专题

想要学习顺序表,我们首先需要了解一下线性表。

2024-08-01 17:59:46 936

原创 库函数qsort的使用讲解

相信各位根据以上这个小例子已经明白了qsort函数的实现原理,那我们就使用qsort函数实现一下不同类型数据存放在一个结构体中的排序吧。int(*compare)(const void*,const void*):函数指针,指向的是两个函数的比较函数。size_t size:是base指向的待排序数组的元素的大小。void* base:指针,指向的是待排序的数组的第一个元素。size_t name:是base指向的待排序数组的元素个数。以上就是qsort函数实现的基本要素。

2024-07-22 20:49:25 184 1

原创 回调函数讲解

如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数。如果我们想要调用一个函数,最常见的方法是使用函数名调用。我们会发现,这样实现这个计算器会有很多重复的代码,虽然执行计算的逻辑是区别的,但是输入输出的操作是冗余的,所以我们会通过使用回调函数的方法来使代码变得更简洁一点。如果使用回调函数,只有调用函数的逻辑是有差异的,我们可以把调用的函数的地址以参数的形式传递过去,使用函数指针接收,函数指针指向什么函数就调用什么函数。

2024-07-22 15:47:40 223

原创 扫雷游戏的设计

所以我们应当使用while循环,来限定循环的条件。我们需要应用一个while循环使整个游戏可以循环进行,但是循环不能无限的进行下去,循环需要在适当的时候停止,所以我们定义一个变量win,定义win为当前已经排查的坐标数,也可以理解为已经进行的局数。然后需要将棋盘打印出来,前面已经提及,在玩儿游戏时,不需要显示mine棋盘,只需要显示show棋盘,所以,mine棋盘不用打印。需要创建两个棋盘,一个棋盘用来存雷,一个棋盘用来排雷,在我们玩儿游戏时,是不需要看到存雷的棋盘的,只需要看到排雷的棋盘就可以了。

2024-01-30 12:25:38 1140 1

原创 2024-01-23 C语言分支循环语句——语句及循环

2·for循环的执行流程:首先执行表达式1初始循环变量,接下来就是执行表达式2的判断部分,表达式2的结果如果==0(为假),则循环结束;=0(为真)则执行循环语句,循环语句执行完后,再去执行表达式3,调整循环变量,然后再去表达式2的地方执行判断,表达式2的结果是否为0(为假),决定循环是否继续。2·do-while循环的执行流程:首先执行语句,执行完语句。do-while循环是先直接进入循环体,执行循环语句,然后再执行while后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不再继续循环。

2024-01-29 21:18:13 359

原创 2024-1-23 C语言分支循环语句——操作符

|:或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)&&:与运算符,就是并且的意思(两侧表达式都为真,则为真,否则为假)如果exp1为假,exp3计算,计算的结果是整个表达式的结果。4·相等运算符==与赋值运算符=是不同的。C语言逻辑运算符有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。1·对于&&操作符来说,左边操作数的结果是0(假)的时候,右边操作数就不再执行。计算逻辑为:如果exp1为真,exp2计算,计算的结果是整个表达式的结果;

2024-01-29 21:17:42 490

原创 开始学习编程的第一天

从小呢,我就很喜欢看小说,长大了就喜欢写小说,这也导致我与咪咕文化这家公司结下了不解之缘,所以,如果有机会,如果我有能力,我想将咪咕文化作为我的目标,进入这家我从小就与之羁绊的公司。当然,学习编程并不能靠一腔热血,坚持与计划都是十分重要的。今天是我正式开始学编程的第一天,我打算在三到四个月的时间内将C语言扎扎实实的学完,在学习完C语言后,我也将通过实战与做题等方式加深我对C语言的理解以及熟练程度。活泼开朗,热情大方也是我的性格特点,所以,简书上有喜欢我的文章的宝贝们可以多多关注我哦,我会超级开心哒~

2024-01-29 21:17:06 447

空空如也

空空如也

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

TA关注的人

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