自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux:基础IO

缓冲区是内存空间的⼀部分。也就是说,在内存空间中预留了⼀定的存储空间,这些存储空间⽤来缓冲输⼊或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输⼊设备还是输出设备,分为输⼊缓冲区和输出缓冲区。

2025-02-25 20:55:43 1248

原创 C++:红黑树

假设我们把新增结点标识为c(cur),c的⽗亲标识为p(parent),p的⽗亲标识为g(grandfather),p的兄弟标识为u(uncle)。

2025-02-13 16:55:41 398

原创 Linux:进程控制

• 另外,进程⼀旦变成僵⼫状态,那就⼑枪不⼊,“杀⼈不眨眼”的kill -9 也⽆能为⼒,因为谁也没有办法杀死⼀个已经死去的进程。通常,⽗⼦代码共享,⽗⼦再不写⼊时,数据也是共享的,当任意⼀⽅试图写⼊,便以写时拷⻉的⽅式各⾃⼀份副本。新进程为⼦进程,⽽原进程为⽗进程。• ⼦进程退出,⽗进程如果不管不顾,就可能造成‘僵⼫进程’的问题,进⽽造成内存泄漏。通过父进程的变量,传地址让waitpid()把子进程结束时的返回值写入父进程的变量。• ⽗进程通过进程等待的⽅式,回收⼦进程资源,获取⼦进程退出信息。

2025-01-21 09:57:59 1100

原创 C++:异常

有时catch到⼀个异常对象后,需要对错误进⾏分类,其中的某种异常错误需要进⾏特殊的处理,其他错误则重新抛出异常给外层调⽤链处理。捕获异常后需要重新抛出,直接 throw;就可以把捕获的对象直接抛出。当异常抛出类型未捕获时,不想程序终止,用catch(…

2024-12-25 22:41:44 418

原创 C++:AVL树

key,vaule的二叉搜索树,需要用三叉链,多定义的父亲指针用来更新平衡因子。旋转总共分为四种,左单旋/右单旋/左右双旋/右左双旋。2、让旋转的树从不满⾜变平衡,其次降低旋转树的⾼度。左边的高度大于右边时右旋转。

2024-12-21 22:44:57 723

原创 Linux:进程的概念

输入/输出设备称为外设,Input/Output->IO,站在内存的角度理解IO。对应的每个数字目录都是一个进程,数字对应的是进程的pid。在父进程里的代码中fork()返回值是子进程的pid。• 内核(进程管理,内存管理,⽂件管理,驱动管理)课本概念:程序的一个执行实例,正在执行的程序等。Linux系统所以的进程都是被它的父进程创建的。本来是一个执行流的遇到fork会变成两个执行流。在子进程里的代码中fork()返回值是等于0的。一个父进程可以有多个子进程,进程也是进程树。:键盘,鼠标,话筒,摄像头……

2024-11-25 16:47:48 1488

原创 C++STL--------map和set

set的相关文档默认仿函数是小于,中序遍历为升序传greater仿函数,中序遍历为降序map是一个key/value的结构,相比set而言多了一个绑定的valuemap底层的红黑数节点中的数据,使用pair<Key,T>存储键值和数据。T1 first;T2 second;{}{}{}make_pair是一个函数模版,自己推导变量类型。

2024-11-19 13:28:29 854

原创 Linux:调试器-gdb/cgdb

断点编号 ------ 断点类型---------------------------是否使能----断点地址--------------------------------打的什么断点。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB会暂停程序的执⾏,并通知使⽤者。cgdb跟gdb的使用方法一样,但cgdb更好观察代码,会分屏显示代码。-g选项,让最后形成的可执行程序,添加调试信息—debug模式!-g后生成的.o 文件被链接后的可执行程序占用的空间会变大。指定 行号从指定行号开始显示。

2024-11-19 12:19:29 1249

原创 C++:搜索二叉树

找到N左子树的最大结点R(最右结点)或者N右子树的值最小结点R(最左结点)代替N,因为这两个结点任意一个放到N的位置,都满足二叉搜索树的规则。替代N的意思就是N和R这两个结点的值交换,转而变成删除R结点,R结点符合情况2或情况3,可以直接删除。3、如果⽀持插⼊相等的值,插⼊值跟当前结点相等的值可以往右⾛,也可以往左⾛,找到空位置,插⼊新结点。1、把N结点的父亲对应孩子指针指向空,直接删除N结点(情况1可以当成情况2或者3处理,效果是一样的)3、把N结点的父亲对应孩子指针指向N的左孩子,直接删除N结点。

2024-11-12 13:18:06 846

原创 C++多态

必须指针或者引⽤调⽤虚函数被调⽤的函数必须是虚函数。

2024-11-11 13:14:55 1310

原创 Linux环境基础和基础开发工具使用

先ctrl + v,用h、j、k、l 键选择要注释的行,选择之后然后输入shift +i,//在ESC一下自动完成注释。程序在打印到显示器上是,内容存在缓冲区中,缓冲区的刷新策略是行刷新。静态链接:把我们要的库方法实现,直接拷贝到我们的可执行程序中。查看包服务器中软件包,只找了软件名包含ls 的软件包名字。使用动态链接必须在系统里面存在动态库,动态库也称为共享库。软件源分为稳定软件源和扩展软件源,甚至有更多分类。$<:把依赖文件一批文件一个一个交给对应的命令。修改当前家目录下的.vimrc的配置文件。

2024-11-08 23:00:34 1460 1

原创 深入了解排序

introsort是introspectivesort采⽤了缩写,他的名字其实表达了他的实现思路,他的思路就是进⾏⾃我侦测和反省,快排递归深度太深(sgistl中使⽤的是深度为2倍排序元素数量的对数值)那就说明在这种数据序列下,选key出现了问题,性能在快速退化,那么就不要再进⾏快排分割递归了,改换为堆排序进⾏排序。三路代表的是:一路全部小于,一路全部是相等值,一路全部大于。专治这种有大量重复的。

2024-11-08 17:40:29 320

原创 C++继承

继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段,它允许我们在保持原有类特性的基础上进⾏扩展,增加⽅法(成员函数)和属性(成员变量),这样产⽣新的类,称派⽣类。继承呈现了⾯向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的函数层次的复⽤,继承是类设计层次的复⽤。

2024-11-04 19:33:42 1462

原创 Linux权限

shell就是一个外壳程序,我们输入的命令交给shell,它去和操作系统交流,实现对应的操作。表明以超级用户的身份去执行,但不是谁都能执行sudo,必须是被信任的用户。所以又想共享目录,但又不想让其他人删除目录里的文件,就需要天剑粘滞位。对于一个文件,如果没有r权限,用任何工具都不行。Linux中一切皆文件,所以权限都是文件对角色的限制。修改权限掩码,到达修改Linux文件缺省 权限的问题。+t :t 代表other 的意思,权限位x变成了t。1、Linux在多用户下,对文件的访问,是隔离的。

2024-10-29 12:10:36 768

原创 Linux基础指令

当我们Ctrl+a选择删除文件时,默认隐藏文件时不会被选中的,可以避免我们对重要数据误操作。以-开头的称为普通文件:文本文件,二进制可执行,动静态库,视频,音频,图片……不光能显示当前路径下的文件也可以显示指定路径的文件,路径称为绝对路径。以自己的当前路径为参照点,查找定位目标文件的路径:相对路径。家目录是保护用户私有信息的目录,默认登录的地方就在家目录。Linux中,以.开头的文件或者目录是隐藏文件。ls:白色文字的是普通文件,蓝色的是目录。Modify: 最后一次修改文件的时间。

2024-10-28 11:33:02 399

原创 C++模版

来解决存储数据类型的问题,但如果存储了一个类型的数据,就不用用栈存储另一个类型的数据,栈不能进行同时存在多个类型数据进行存储。也可以由程序员控制让模版生成什么类型的函数来调用,称为显示实例化。在针对不同类型时也可以使用强转让编译器知道要实例化什么类型的函数。所以还是用模版生成栈可以同时存在用来存储不同类型的数据。对于需要不同类型模版也可以实现,需要定义多个参数类型。在调用时根据不同类型编译器生成一个匹配该类型的函数。前面编译器自动推导后生成的函数是隐式实例化。模版生成的函数就是逻辑一样,就是类型不一样。

2024-10-28 11:32:44 1110

原创 C++STL--------stack栈和queue队列

实现的初心是为了替代vector和list,但效率上都不上,list把插入删除的效率做到极致,vector把访问效率做到极致,deque克服了vector和list的缺点但访问比不上vector,中间位置插入删除又比不上list。stack就是适配器,把设计好的数据结构让stack来进行复用,通过传模版参数,形参不同的栈数据存储形式,链式栈或者是数组栈等等,就是负责完成后进先出的效果。队列也一样,只要实现效果是先进先出就可以,不用管底层是如何实现的,底层也是复用已经实现好的数据结构来完成的。

2024-10-27 11:46:01 431

原创 C++STL--------list

是一个支持O(1)时间复杂度插入和删除的链表结构,迭代器是双向的,底层是一个带头双向循环链表。跟push_back有差异,push_back要插入的类型被固定,可以支持隐式类型转换。list 自己实现的sort是支持双向迭代器的,算法库里的sort是传随机迭代器。emplace_back不支持隐式类型转换,但可以直接传要初始的值进行构造。比算法库里的swap更高效,底层是交换指向头结点。可以调整链表里面的顺序,把自己的结点转移给自己。位置用迭代器表示,也可以删除一个迭代器区间。插入1到9,打印9到1。

2024-10-22 18:24:09 1436

原创 C++STL--------vector

是一个类模版,可以创建各种类型的数组。

2024-10-14 23:51:44 640

原创 Linux远程连接服务器

文章目录

2024-10-10 15:15:46 503

原创 C++STL--------string

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

2024-10-07 18:45:48 1302

原创 类的初始化列表

C++支持内置类型和类类型的相互转换class Apublic:A(int n):_a1(n),_a2(_a1)private:int main()A aa1 = 1;return 0;用整形 1 创建了一个临时的A构造函数,拷贝构造给了aa1但因为构造加拷贝构造太浪费了,就直接优化为直接构造看上图,编译器只执行了一次构造函数。如果不想让隐式类型发生转换可以在前面加explicit:_a1(n),_a2(_a1)当有多个参数转换时,用大括号括起来class A。

2024-09-16 22:56:00 1575

原创 C++运算符重载

如果不写赋值运算符重载函数,系统会自动生成,但是浅拷贝,一个字节一个字节的拷贝,对于占用资源的还是要自己写才好。对于类类型的使用运算符编译器是不知道要干嘛的就需要自己写函数,自己实现功能。要跟拷贝构造区分,拷贝构造是一个已经存在,给另一个初始化时进行的拷贝操作。日期 - 日期,日期 + 天数,日期 - 天数,这些都是有意义的。总结如果显示写了析构,就要显示写赋值运算符重载。对两个已经存在的类的对象进行赋值拷贝操作。运算符的作用,用于定义类的成员函数指针。就比如日期类的大小比较。

2024-09-09 21:20:50 3464

原创 《C语言实现各种排序算法》

希尔排序法的基本思想是:先选定⼀个整数(通常是gap = n/3+1),把待排序⽂件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排序,然后gap=gap/3+1得到下⼀个整数,再将数组分成各组,进⾏插⼊排序,当gap=1时,就相当于直接插⼊排序。直接插⼊排序是⼀种简单的插⼊排序法,其基本思想是:把待排序的记录按其关键码值的⼤⼩逐个插⼊到⼀个已经排好序的有序序列中,直到所有的记录插⼊完为⽌,得到⼀个新的有序序列。快排的时间复杂度:O(n。快排的空间复杂度:O(

2024-08-20 23:11:06 851 1

原创 C++构造和析构

构造函数的名字跟它所在的类的名字一样,构造函数没有返回值(viod 也不用写),构造函数支持重载,就是根据传参来区分调用哪一个构造函数。内置类型是int/char/double/指针等类型,自定义类型是class/struct关键字创建的类型。构造函数是一个类的成员函数,在类创建好后(就是开劈好空间)自动调用构造函数对类的成员变量进行初始化。编译器自动生成的构造函数对内置类型有可能不做处理,对自定义类型会调用对应的构造函数。总结就是不传实参就调用的构造叫默认构造。在不传参时调用构造函数不用加括号。

2024-08-12 16:24:50 1030

原创 C++类和对象

calss是定义类的关键词,用法更C语言中的结构体struct关键词用法一样,区别是类可以在里面创建函数,当然在C++中也是兼容结构体的,同样也对结构体进行升级也可以包含函数了。在类里面的函数默认是被内联函数inline修饰的。C++中的类和结构体的用法相同,区别在于默认的限制访问。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或者成员函数。

2024-08-06 22:58:50 1307

原创 C++入门基础

定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下⾯的rand不在冲突了。C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。

2024-08-03 16:49:45 1290

原创 《数据结构:链表递归实现二叉树》

⽤链表来表⽰⼀棵⼆叉树,即⽤链来指⽰元素的逻辑关系。根结点的左⼦树和右⼦树分别⼜是由⼦树结点、⼦树结点的左⼦树、⼦树结点的右⼦树组成的,因此⼆叉树定义是递归式的,后序链式⼆叉树的操作中基本都是按照该概念实现的。⼆叉树分为空树和⾮空⼆叉树,⾮空⼆叉树由根结点、根结点的左⼦树、根结点的右⼦树组成的。:先打印根节点,然后打印左子树,最后打印右子树。:先打印左子树,再打印根结点,最后打印右子树。:先打印左子树,再打印右子树,最后打印根结点。

2024-07-27 17:08:40 316 1

原创 《数据结构:顺序实现二叉树》

对于深度为 K 的,有 n 个结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。现实中我们通常把堆(⼀种⼆叉树)使⽤顺序结构的数组来存储,需要注意的是这⾥的堆和操作系统虚拟进程地址空间中的堆是两回事,⼀个是数据结构,⼀个是操作系统中管理内存的⼀块区域分段。树形结构中,我们最常⽤的就是⼆叉树,⼀棵⼆叉树是结点的⼀个有限集合,该集合由⼀个根结点加上两棵别称为左⼦树和右⼦树的⼆叉树组成或者为空。

2024-07-22 15:40:33 824

原创 《数据结构:栈和队列》

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行插入和删除操作的一端称为栈顶,另一端称为栈底。概念:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)队列也可以由数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。:栈的插入操作叫做进栈/压栈/入栈/,入数据在栈顶。

2024-07-19 21:34:02 744 1

原创 《数据结构:C语言实现双链表》

带头链表中的头结点,实际为“哨兵位”,哨兵位结点补存储任何有效元素,只是站在这里“放哨的”虽然有这么多的链表的结构,但我们实际中最常用的还是两种结构:单链表和双向带头循环链表.

2024-07-19 16:10:30 520

原创 《数据结构:C语言实现单链表》

当我们想要保存⼀个整型数据时,实际是向操作系统申请了⼀块内存,这个内存不仅要保存整型数据,也需要保存下⼀个结点的地址(当下⼀个结点为空时保存的地址为空)。在有数据的情况下,要找到最后一个结点,最后一个结点存放的指针指向的地址为NULL,把这个节点的指针指向为新结点。在数据为5的结点前面插入新结点,要传三个值,第一个是首结点,第二个要在哪个结点之前插入结点,第三个插入的数据值。思路在开辟新结点,需要用首结点找到插入结点之前的结点,让之前结点指向新结点,新结点指向被插入的结点。

2024-07-13 14:37:39 1055 1

原创 《数据结构:C语言实现顺序表》

创建完成就一步步实现1、在squence_list.h的文件,首先要创建顺序表所要用到的结构体自定义类型//sequence_list.h文件中//顺序表存放数据的类型//顺序表的类型创建//存放指定类型数据的指针//存放数据的有效个数int count;//属性表空间大小int size;}SL;//重命名一个简单的名字。

2024-07-11 19:33:46 742

原创 算法的复杂度

实际中我们计算时间复杂度时,计算的也不是程序的精确的执⾏次数,精确执⾏次数计算起来还是很⿇烦的(不同的⼀句程序代码,编译出的指令条数都是不⼀样的),计算出精确的执⾏次数意义也不⼤,因为我么计算时间复杂度只是想⽐较算法程序的增⻓量级,也就是当N不断变⼤时T(N)的差别,上⾯我们已经看到了当N不断变⼤时常数和低阶项对结果的影响很⼩,所以我们只需要计算程序能代表增⻓量级的⼤概执⾏次数,复杂度的表⽰通常使⽤⼤O的渐进表⽰法。空间复杂度也是⼀个数学表达式,是对⼀个算法在运⾏过程中因为算法的需要额外临时开辟的空间。

2024-07-10 20:08:26 1362

原创 《C语言》预处理

C语言设置了一些预定义符号,可以直接使用,在预处理期间进行处理的。__FILE__//进行编译的源文件__LINE__//文件当前的行号__DATE__//文件被编译的日期__TIME__//文件被编译的时间__STDC__//如果编译器遵循ANSI C,其值为1,否则未定义100逻辑规则是帮后面代码中出现MAX直接替换成100,这个操作步骤是在预处理阶段完成的,一般在用#define定义常量时的名称用大写书写。

2024-07-07 13:44:02 930

原创 《C语言》编译和链接

程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留它们的值。链接会生成一个表记录函数名有没有被声明,变量名赋值等等,一个文件定义了一个函数,另一个文件中没有声明这个函数也可以使用的原因就是因为链接产生的效果。将源代码程序输入扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成一系列的记号(关键字、标记符、字面量、特殊字符等)。在使用编译器编写代码时,编写的代码是高级语言,机器无法直接识别和运行,在编译器内部会翻译成机器可执行的机器语言。

2024-06-25 17:29:45 1000

原创 《C语言》文件操作

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。程序中的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着的字符河。我们写的程序是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。

2024-06-16 23:06:07 1377

原创 《C语言》动态内存管理

所以如果我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务。C语言还提供了一个函数叫calloc,calloc函数也是用来开辟动态内存空间的。这个函数可以向内存申请一块连续可用的空间,并返回指向这块空间的指针。动态内存开辟的函数需要引入头文件<stdlib.h>这样的柔性数组相当于获得了十个整形空间。free函数用来释放动态开辟的内存。内存分为栈区、堆区和静态区。用来调整动态内存空间。

2024-06-16 03:46:15 1467 6

原创 《C语言》联合体和枚举

从中可以发现结构体的内存比联合体的内存大一些,在成员一样的情况下联合体会省许多空间。使用方式跟结构体一样,联合体也可以由多个不同类型的成员组成。缺点是:在联合体中改变一个成员的值,其他成员的值也会被改变。在使用时会感觉联合体跟结构体一样,那它们直接有什么区别呢。知道联合体省空间,但需要注意它虽然省空间,但也有缺点。创建一个结构体和一个联合体,它们的成员相同。联合体的成员会因为另一个成员的变化而变化。通过打印联合体成员中的地址可以发现。因此联合体的成员不能同时使用。可以发现成员的地址都是一样的。

2024-06-13 20:39:40 755 3

原创 C语言结构体

位段的声明和结构是类似的,有两个不同:1、位段的成员必须是 int、unsigned int 或signed int,在C99中位段成员的类型也可以选择其他类型。2、位段的成员名后边有⼀个冒号和⼀个数字。//占一个bit位int b : 2;int c : 4;位段可以节省空间。

2024-06-09 01:02:51 632 3

空空如也

空空如也

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

TA关注的人

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