自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【Linux】进程(9):进程控制3(进程程序替换)

先直接看代码和现象,execl函数先不用管,后面会说到通过结果我们发现,进程在执行完第一个printf函数后,执行的是ls -a -l的命令,而且不再执行第二个printf函数。所以,我们可以看出,execl函数的作用是让进程通过execl函数,执行新的程序。还是不理解,现在让我们来了解进程程序替换的原理。

2024-07-10 18:00:00 802

原创 【Linux】进程(9):进程控制2(进程等待)

睡眠8秒后,父进程等待子进程退出,子进程已经退出,wait函数得到子进程的pid,解决子进程退出的僵尸问题。我们上面讲的,都是如果子进程没有退出,那么父进程在执行waitpid时在阻塞等待,这表示在等待期间,父进程其它事情什么都没有干。其中次8个比特位表示退出状态,即退出码。上面代码的意思是,如果子进程代码跑完了,即正常退出,那么查看子进程的退出码。当然不能,因为进程具有独立性,子进程写入时,会先发生写时拷贝,所以父进程看不到子进程写入的数据,因此不能使用全局变量来接收退出码和退出信号。

2024-07-10 06:00:00 1031

原创 【Linux】进程(9):进程控制1

exit底层调用的就是_exit,因为杀掉进程本质就是释放进程对应的代码和数据,释放进程的除pcb以外的其它内核数据结构。一个进程结束,系统会释放它对应的代码和数据的空间,释放内核数据结构(mm_struct和页表),但是task_struct会维持一段时间,变成Z状态(僵尸状态),系统会将进程的退出码和退出信号写入进程的task_struct中,等待父进程进行读取。

2024-06-09 07:00:00 2129 1

原创 【Linux】进程(8):Linux真正是如何调度的

假如此时active指针指向array[0],那么CPU调度进程时,就访问array[0]的quene[140],这时array[0]的quene[140]的队列只出不进:进程结束,就从CPU上剥离进程的pcb;等到本quene[140]中没有进程了,就将active指向array[1],让empired指向array[0],CPU运行进程时,就访问array[1]的quene[140],此时它就变成了只出不进,另一个就是只进不出。可能有人会说了,那这不还是要遍历吗,看每一个下标对应的比特位是否为0?

2024-06-07 18:00:00 1165

原创 【Linux】进程(7):地址空间

在小学的时候,大家都应该和同桌在桌子上划过“三八线”吧,现在假设你和同桌2个人共用一个100cm的桌子, 你们每个人50cm,那这如何用计算机语言来描述呢?只需要构建2个结构体,第二个结构体表示一个课桌分为左右两部分,第一个结构体表示每部分的开始和结束位置,再构建第二个结构体的结构体变量,最后将左右两块空间的起始和终止位置都赋值即可如果同桌太过分了,每次都侵占了属于你的10cm区域,再用计算机语言来描述事实上,地址空间本质是内核的一个struct结构体(struct mm_struct)

2024-06-07 06:45:00 1019

原创 【Linux】进程(6):环境变量

当我们登录Linux系统时,环境变量对应的配置文件被加载到了bash进程中,所以默认我们查到的环境变量是内存级的,我们对环境变量PATH的修改也是在内存里修改,并不影响环境变量对应的配置文件。对于./myprocess进程,其父进程是bash,且在Linux登录时,环境变量对应的配置文件被加载到了bash进程中,所以./myprocess进程能看到并访问bash的数据(环境变量)是可以理解的。在Linux系统中,有80%的命令都是bash创建子进程执行的,如:ls,mkdir,cp等;

2024-06-05 18:00:00 918

原创 【Linux】进程(5):命令行参数

在我们命令行输入的时候,Linux中会有一些内部的功能将输入的整体的字符串打散成4个字符串:./myprocess ,-a,-b和-c(它们之间以空格作为分隔符)。根据上面的代码,我们能够感觉到,数组argv是个变长数组,最后一个元素指向NULL,argc是数组的非NULL元素个数,我们以./myprocess -a -b -c为例。第二个参数明显是指针数组,每个元素的类型是char*,这说明每个元素指向的要不是字符,要不是一个字符串,它的作用是存储用户从命令行输入进来的参数。

2024-06-05 06:00:00 569

原创 【Linux】进程(4):优先级

优先级是指定进程获取某种资源(如CPU)的先后顺序一个进程有一个task_struct结构体,所以里面有许多内部字段,内部字段中存在几个与优先级有关的数据(如:int prio=?Linux中优先级数字越小,优先级越高。

2024-06-03 18:00:00 506

原创 【Linux】进程(3):运行,阻塞,挂起

但是在时间片内,进程1还没有执行完成,要从CPU上剥离,这时CPU会将寄存器内的临时数据存入进程的task_struct中,CPU的寄存器内的临时数据也叫进程的上下文,即将上下文数据存入task_struct中。等到用户按了键盘上的按键,通过驱动程序会被操作系统最先知道,知道之后,将设备的struct device的工作状态改为ok,再将在设备队列里的进程重新链回到运行队列中(这个过程叫唤醒),等CPU再次调度时,会执行scanf后续代码,将键盘设备的数据读取。我们知道,操作系统是管理软硬件资源的。

2024-06-03 07:00:00 1332

原创 【Linux】进程(2):进程状态

如果没有父进程读取,该进程虽然已经运行完毕但task_struct会一直存在,即僵尸进程,task_struct占的空间非常大,这就导致内存泄漏。因为直接在命令行中启动的进程,它的父进程是bash,bash会自动读取新进程的退出信息,然后由操作系统释放。编译.c文件,运行进程,通过每秒显示的进程信息中我们发现,进程处于S+状态,而非R状态(运行状态),这是为什么?

2024-05-31 18:00:00 967

原创 【Linux】进程(1)

父进程的代码和数据是从磁盘加载过来的,子进程的代码默认继承父进程的代码,数据我们后面会学:如果子进程没有写入,那父子进程的数据也是共享的,如果父子进程中有一个要对数据进行写入,那么会发生写时拷贝,数据就不共享了。所以,如果没有存储器(内存),那么一台电脑的成本就高,而高成本的东西是不利于广泛传播和使用的,所以内存的存在还是非常有必要的。第一行是我们所找的myprocess进程,第二行是我们使用grep命令所运行的进程,记得吗,我们前面讲的,在Linux中运行的大部分执行操作,本质都是运行进程。

2024-05-31 08:25:44 994

原创 【Linux】调试器-gdb使用

在上面的print/p命令中,想要知道每次循环时a/&a,就要在每次循环时print/p a/&a,很麻烦,且没有必要,所以出现了display,只要display a/&a,在每次循环时,自动出现a/&a。

2024-05-14 08:00:00 1021 1

原创 【Linux】git

如下面的,先建立一个后缀名为.o的文件test.o,再git add . ,再用git status,发现与之前相比没有变化,所以提示说没有能提交的。git push:将git的本地仓库同步到git的远端仓库,此时在gitee上我们刷新一下就能看到有ProcessBar文件夹。等到我们将git的本地仓库同步到git的远端仓库,我们就能在gitee刷新后的界面中看到。

2024-04-17 20:20:32 1112

原创 【Linux】进度条

7。

2024-04-17 09:00:00 818

原创 【Linux】Linux编译器-gcc/g++使用

Linux中编译程序后默认的可执行程序的文件名为a.out,这也可以被修改。用gcc filename -o you.exe或者gcc -o my.exe filename (-o my.exe 要与filename相邻)。g++同理Gcc命令:gcc -DV1 test.c / gcc -D V2 test.c /gcc -DV3=1 test.c(-D和V1之间可以有空格,也可以没有)

2024-04-10 21:31:36 1348

原创 【Linux】vim

在命令模式下,先对100或101行yy,再p一下,然后按shift+i再进入插入模式,将用户名改为zkj。我们可以实现命令模式和插入模式的转换,命令模式和底行模式的转换,那么能否直接实现插入模式和底行模式的转换呢?按wq退出时,会报错,别慌,只需要将wq改成 wq!

2024-04-10 09:00:00 841

原创 【Linux】权限理解

就是通过一定的条件,拦住一部分人,给了一部分人权力,来访问某种资源。比如:腾讯视频的vip能看一些非vip不能看的电影。

2024-04-02 19:10:11 1166 1

原创 【Linux】常见指令

说明: cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录, 则它会把前面指定的所有文件或目录复制到此目录中。我们发现,对这种行数比较多的文件说不适合用cat来查看的,因为它直接到了最后,而且不能通过上键和下键来滑动查看,所以我们接下来了解一些适合查看大文件的指令。Log.c只是将文件先打开再关闭,没有写入内容,因为以w的方式打开文件时,先清空文件,所以运行了log.c后,test.txt的内容大小为0。如果我们真的要删除,键盘输入y,如果不想删除,键盘输入n。

2024-04-02 09:00:00 888

原创 【leetcode】左叶子之和

其次,不是空树,如果某个节点的左孩子节点是叶子节点,那么返回左孩子节点的值与递归该节点的右子树返回的值之和。如果某个节点的左孩子节点不是叶子节点,那么返回递归该节点的左子树返回的值与递归该节点的右子树返回的值之和。这道题比较简单,如果你还是有些不清楚的话,建议画个递归流程图。

2024-03-28 10:34:26 286 1

原创 【leetcode】环形链表的约瑟夫问题

很简单,让cur先走,prev指向cur的前一个结点,如果报到2,让prev指向cur的下一个节点,再free(cur)即可。上面的思路中,如果有人报到2,让前一个结点指向该节点的后一个节点,再释放该节点,这该如何实现呢?首先我们要明确一点,题目要求我们要用环形链表,所以用数组等是不被允许的。

2024-03-28 10:23:25 479

原创 【数据结构】计数排序

按照上面的思想,数组count的下标都从0开始的话,如果数组a为{1000,1111,1222,1333,1444,…,2000},那么我们要开辟count数组,数组下标从0开始到2000结束,前1000个空间都被浪费了,所以我们还可以改进一下。可想而知,如果有一个数组的所有的值相差不大,那计数排序的效率是非常高的。这样我们就能知道数组a的元素范围range,动态开辟有range个元素的数组count,为了方便,我们用calloc函数开辟,这样count的每个元素的初始值都为0。

2024-03-27 21:44:32 441

原创 【数据结构】归并排序(不用递归)

注意:上面的图只是为了方便看才感觉是在原数组上修改的,实际上是先比较2个数组,之后将这2个数组合成的数组存入额外的数组tmp中,之后再拷贝回原数组。问题:当原数组的数组元素不为2^n时,2个数组可能会越界,如下图:1还要与不是数组元素的值相比。所以我们要处理2个数组下标越界的可能。

2024-03-27 17:38:57 485

原创 【数据结构】归并排序(用递归)

将数组不断分成2部分,直到这两个部分都是一个元素,将这两个部分当成两个数组,因为都是只有一个元素,所以这两个数组都是有序的,再将两个有序数组合并成一个有序数组。再看10和6的右半边是1和7,将这两个部分当成两个数组,因为也是只有一个元素,所以这两个数组都是有序的,再将两个有序数组合并成一个有序数组1,7。然后将有序数组6,10和1,7再次合并成一个有序数组1,6,7,10……归并排序核心步骤:。在讲归并排序之前,问问自己,如果有两个数组都是有序的(升序),如何将这两个有序数组合并成一个有序数组呢。

2024-03-24 19:58:19 470

原创 【数据结构】快速排序(不用递归)

我们先插入数组的末尾元素的下标,再插入首元素的下标。当左右子树为一个元素或者为空时,不用将下标插入栈中,为一个元素的条件是:left==keyi - 1或者keyi + 1 ==right,为空的条件是left > keyi - 1或者keyi + 1 > right。

2024-03-24 11:47:02 245

原创 【数据结构】快速排序(用递归)

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列重复该过程,直到所有元素都排列在相应位置上为止。1.定义3个变量key,prev和cur来表示数组的下标,prev和key置为第一个元素的下标,cur置为第二个元素的下标。3.当a[cur]

2024-03-22 21:48:15 1283

原创 【数据结构】选择排序

在这个数组里,第一次排序时,最大值的下标maxi==begin,当交换下标为begin和mini的值后,a[begin]==1而不是 ==10,此时再交换下标为end和maxi的值时,就是1和2交换。每一次从待排序的数据元素中选出最小(或最大或最小和最大)的元素,存放在序列的起始位置(或末尾位置或起始和末尾位置),直到全部待排序的数据元素排完。那我们再试试下面的数组呢,这也是正确的吗?

2024-03-22 17:01:33 528

原创 【数据结构】希尔排序

排序的目的是让数组从接近有序到有序。希尔排序法的基本思想是:先选定一个整数gap,把待排序文件中所有记录分成gap个组,所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后,取gap=gap/2或者gap=gap/3+1(里有下面会说),重复上述分组和排序的工作。3.希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些书中给出的希尔排序的时间复杂度都不固定。

2024-03-19 21:47:50 1084

原创 【数据结构】直接插入排序

(N-1) = (N+1)(1+N-1)/2 = N*(N-1)/2,所以时间复杂度为O(N^2)……+(N-1) = (N+1)(1+N-1)/2 = N*(N-1)/2,所以时间复杂度为O(N^2)。下面代码中,因为最后一个元素一定是tmp,所以end+1

2024-03-19 12:10:51 1235 1

原创 【数据结构】实现二叉树

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。顺序存储顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆我们后面的章节会专门讲解。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。链式存储二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。

2024-03-19 07:00:00 964 1

原创 【数据结构】树和二叉树

注意:树形结构中,子树之间不能有交集,否则就不是树形结构。

2024-03-15 20:25:41 839 2

原创 【leetcode】二叉树的前序遍历➕中序遍历➕后序遍历

根据提示,我们应该先动态开辟一个数组,之后按前序遍历的顺序将二叉树的值插入数组中,最后再返回这个数组。我们再来看函数给定的形参是什么:root是指向二叉树的根节点的指针,*returnsize是数组的大小,而非题目给我们已经开辟好的数组。然后,我们将二叉树的值按前序遍历的顺序放入数组中。首先我们要想开辟数组,那么我们需要知道数组的大小,也就是二叉树的节点总数,用下面这个函数来返回节点总数。

2024-03-15 17:22:23 524

原创 【leetcode】相同的树➕对称二叉树➕另一棵树的子树

我们仔细看代码,当root->val==subRoot->val时,返回isSameTree(root,subRoot)的值,如果返回false,那么。这道题同相同的树相似,只不过相同的树是比较2个树的同侧子树,而这道题是比较不同侧子树。好了,那本题的代码很轻易地就写出来了,那这对不对呢?

2024-03-12 21:47:56 395

原创 【leetcode】单值二叉树

点击查看题目思路:好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

2024-03-12 20:54:54 347

原创 【数据结构】堆的TopK问题

TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决。

2024-03-06 21:31:52 1200 5

原创 【数据结构】堆排序

上面的2利用了插入思想,从第二个元素插入开始判断位置是否合适,不合适就向上调整,调整结束后,再插入并判断第三个元素是否合适……也就是说,在再次插入元素之前,所有的元素已经构成了大堆,插入元素后,再次调整直到为大堆?插入第二个元素判断位置是否合适,如果该节点的值>双亲结点的值就向上调整,调整结束后,再插入并判断第三个元素是否合适。的顺序存储方式存储在一个一维数组中,并满足:任意一个双亲结点的值=孩子节点的值),则称为。如果有一个关键码的集合K,把它的所有元素按。

2024-03-06 16:56:33 1007

原创 【数据结构】实现堆

数据插入完成后,我们还要保证这是一个小堆,所以要对比这个数据和它的双亲结点的值:如果它的值要大于双亲结点的值,那位置就不要动;如果它的值要小于双亲结点的值,为了让这个堆还是小堆,我们要将它和双亲结点互换位置,直到它的值要大于双亲结点的值或者它已经是根节点。的顺序存储方式存储在一个一维数组中,并满足:任意一个双亲结点的值=孩子节点的值),则称为。因为函数的实参是HP类型变量的地址,不可能为空,所以对它断言,下面的接口同理。如果有一个关键码的集合K,把它的所有元素按。

2024-03-04 21:42:14 1097 1

原创 【leetcode】用栈实现队列

在做此题之前,我们先要实现栈,这在上个博客中已经写过,在这就不在赘述,下面是实现队列的代码。

2024-03-02 19:42:55 383 7

原创 【leetcode】用队列实现栈

在做此题之前,我们先要实现队列,这在上个博客中已经写过,在这就不在赘述,下面是实现队列的代码。现在我们来写本题的代码。

2024-03-02 17:01:22 583 1

原创 【leetcode】有效的括号

如果觉得没有的话,请往上看我们注意的第二条:要将栈销毁。在上面这段代码中只有返回true时才销毁了栈,返回false时都没有销毁。其实最后判断是否为空,不为空返回false,为空返回true也可以写成这样。实现栈在上个博客中已经写过,在这就不在赘述。上面是实现栈的代码,下面写本题代码。

2024-03-02 15:48:39 455

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

assert(pq);8。

2024-03-02 11:56:45 824

空空如也

空空如也

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

TA关注的人

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