- 博客(52)
- 收藏
- 关注
原创 TCP协议
目录TCP报文段首部TCP连接建立(三次握手)TCP连接释放(四次挥手) MSS最大报文段长度TCP可靠传输确认应答机制超时重传机制滑动窗口机制滑动窗口向前滑动滑动窗口丢包问题发送窗口大小0窗口拥塞控制机制(1)源端口和目的端口:各占2个字节,分别写入源端口号和目的端口号。(2)序号:占4字节,在一个TCP连接中每一个字节都按顺序编号。整个要传送的字节流的起始序号都必须在连接建立时设置。首部中的序号字段值指的是本报文段发送的数据的第一个字节的序号(3)确认号:占4字节,是期望收到对方下一个报文段的第一个数
2022-06-18 21:27:12
1607
原创 AVL树(插入)
目录AVL树的概念AVL树节点的定义AVL树的插入AVL树的旋转左单旋右单旋右左双旋左右双旋完整代码AVL树的插入AVL树就是在二叉搜索树的基础上引入了平衡因子,因此AVL树也可以看成是二叉搜索树。那么AVL树的插入过程可以分为两步: 1. 按照二叉搜索树的方式插入新节点 2. 调整节点的平衡因子代码如下:以上代码中_root为AVL树底层维护的指针,指向AVL树的根节点,对于插入节点我们并不陌生,在平衡因子为1或者-1时,需要向上调整平衡因子也非常好理解。而当平衡因子为
2022-06-04 23:27:54
989
原创 二叉搜索树(C++)
目录二叉搜索树的概念 二叉搜索树操作二叉搜索树的查找二叉搜索树的插入 二叉搜索树的删除要删除的结点无孩子结点要删除的结点只有右孩子结点要删除的结点只有左孩子结点要删除的结点有左、右孩子结点都存在代码实现使用模板类,可以存放任意类型的元素。然后就可以定义二叉搜索树了,代码如下:代码中要注意的点就是当树为空时要插入元素,直接插入返回。当待删除节点是根节点时,需要改变底层维护的指针_root的指向。
2022-06-02 12:18:12
404
原创 Linux-socket编程
UDP特性无连接:UDP双方在发送数据之前是不需要进行沟通的。只需要知道对方的ip地址和端口号就好。不可靠:不保证UDP数据是可靠,有序的到达对方面向数据报:UDP应用层/网络层递交数据的时候,都是整条数据进行交付的。UDP-Socket编程编程流程服务端:创建套接字,绑定地址信息,接收数据,发送数据,关闭套接字。客户端:创建套接字,绑定地址信息(不推荐),发送数据,接收数据,关闭套接字。创建套接字绑定地址信息的含义:将进程与网卡绑定,进程可以从网卡中接收数据,也可以是通..
2022-05-23 15:24:05
694
原创 Linux多线程(下)
线程安全(下)现在来一小段代码,来演示一下多个线程访问临界资源时保证合理性。假如有两个工作线程,一个工作线程做面,一个工作线程吃面,我们来约定一个规则:1.同一时刻吃面线程去吃面的时候,做面线程不能去做面,反之亦是这样,也就是保证互斥。2.没有面时,吃面线程不能去吃面,有面时,做面线程不能去做面,也就是保证面的数量只能是1或者0(合理访问临界区资源)。代码如下: 1 #include <stdio.h> 2 #include <pthread.h> 3
2022-05-06 17:43:04
1475
原创 C++继承
继承的概念继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。例如以下代码中,Dog类继承了Animal类,那么就可以调用Animal类中的成员方法。继承定义定义格式继承方式以及访问限定符继承方式:public、protected、priv..
2022-04-28 09:59:42
420
原创 vector的简单模拟
目录构造与析构简单方法的模拟拷贝构造与赋值运算符重载浅拷贝问题深拷贝扩容reserve()resize()插入与删除push_back()insert()erase()构造与析构模拟实现时,依然使用vector作为容器的名字,为了防止与std命名空间中的vector冲突,使用自定义的命名空间,将模拟实现的类放入即可。vecotr容器中可以存储多种类型的值,所以需要使用模板的方式。类的实现方法也有多种,以下实现采用三指针的方式,比如容器中的有效元素.
2022-04-13 16:31:17
969
3
原创 Linux进程信号
信号的产生1.通过终端按键产生信号如下代码: 1 #include <stdio.h> 2 #include <unistd.h> 3 int main(){ 4 while(1){ 5 printf("i am test process\n"); 6 sleep(1); 7
2022-03-30 21:56:41
3639
14
原创 C++类与对象(下)
目录再谈构造函数构造函数体赋值初始化列表explicit关键字static成员静态成员变量静态成员函数友元友元函数友元类再谈构造函数构造函数体赋值构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内 可以多次赋值。如何证明?如下日期类中,编译代码后,直接报错说引用类型变量r未初始化,这就说明构造函数中做的工作只是赋值,而不是初始化。初始化列表初始化列表:以一个冒号开始,接着是一个以逗号分隔
2022-03-25 20:57:43
2009
1
原创 Linux进程间通信(下)
共享内存原理1.在物理内存中开辟一段空间2.不同的进程通过页表将物理内存空间映射到自己的进程虚拟地址空间中3.不同的进程通过操作自己进程虚拟地址空间中的虚拟地址,来操作共享内存如下图所示:共享内存接口1.shmget功能:创建或获取共享内存,具体用法如下:2.shmat功能:将共享内存添加到进程虚拟地址空间,用法如下:3.shmdt功能:分离共享内存4.shmid功能:获取或者修改共享内存属性信息,以及删除共享内存。代码验...
2022-03-23 15:26:23
866
原创 Linux进程间通信(上)
匿名管道管道接口pipe函数可以用来创建匿名管道,从而实现进程间通信,函数如下:从PCB角度理解管道先来理解一下pipe()函数的参数到底是什么意思,如下代码:输出了"3,4",这是两个小正数,这很容易让我们想到了文件描述符,那么到底是不是呢?我们使用指令进入以该进程号命名的文件中:显然,这两个参数正是文件描述符,那么这两个文件描述符与匿名管道的关系呢?请看下图来理解:知道了这层关系之后,就可以来用一用这个缓冲区了,如下代码:代码完成的功能只是在同一个进程...
2022-03-16 19:31:58
2189
9
原创 Leetcode 剑指offer 03.数组中重复的数字
找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例 1:输入:[2, 3, 1, 0, 2, 5, 3]输出:2 或 3思路一:暴力遍历法,题目的要求是找到重复的数字,那么如果我们用暴力遍历的方法,第一个数字和后面的比较,如果没有重复i++,然后继续,这种方法需要时间复杂度是O(N^2),太慢,显然这种方法不太合适。...
2022-03-13 19:59:46
359
1
原创 Linux基础IO
C文件接口1.fopenmode打开文件的方式:'r' 只读方式打开,将文件指针指向文件头,如果文件不存在,则返回空。'r+' 读写方式打开,将文件指针指向文件头,如果文件不存在,则返回空。'w' 写入方式打开,将文件指针指向文件头并将文件内容清空。如果文件不存在则创建。'w+' 读写方式打开,将文件指针指向文件头并将文件内容清空。如果文件不存在则创建。'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则创建。'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在
2022-03-05 17:59:49
1551
1
原创 Linux进程控制(下)
进程程序替换替换函数有六种以exec开头的函数,统称exec函数,这些函数都可以用作进程程序替换。下面来介绍这六个函数:1.execl操作系统中的命令其实也是可执行程序,我们使用"pwd"命令来测试一下execl()函数,先使用命令:which pwd 找到"pwd"可执行程序的路径:就接下来姐可以测试这个函数了:代码执行后的现象说明此时进程程序替换成功。2.execlp代码测试:可以看到此时没有带路径,也成功了。为什么此时不带路径也可以替换成功...
2022-02-27 15:39:14
844
1
原创 Linux进程控制(上)
进程终止进程退出场景1.正常退出:从main函数返回、调用exit()、调用_exit()。2.异常退出:ctrl+c、信号终止、空指针访问等。exit与_exit1.exit()函数是用来终止一个进程的,谁调用终止谁:例如以下代码,使用exit()函数来终止一个进程:可以看到,代码执行后只打印出了x的值,exit()函数调用后进程就正常退出了。2._exit()函数也是用来终止一个进程的,谁调用终止谁:如下代码,使用_exit()函数来终止一个进程:..
2022-02-25 13:24:27
801
原创 Linux进程概念
基本概念通俗的观念:程序的一个执行实例,或正在执行的程序。内核的观点:担当分配系统资源(CPU时间和内存)的实体。进程控制块-PCB含义进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。Linux中的PCBLinux操作系统下的PCB是:task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。进程信息使用 ps aux 命令可以查看进程,如下:进程信息也可以进入/p
2022-02-21 18:51:05
1731
5
原创 C++类与对象(中下)
拷贝构造函数拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。特性1. 拷贝构造函数是构造函数的一个重载形式。 2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。3.若未显示定义,系统生成默认的拷贝构造函数如下代码中想把d1对象拷贝给d2对象,代码貌似没有什么问题,但是却编译失败了,为什么呢?因为函数传参得过程中要发生一次值拷贝,在语句 Da.
2022-02-16 14:27:01
670
原创 LeetCode 148.排序链表
题目给你链表的头结点head,请将其按升序排列并返回排序后的链表。示例 1:输入:head = [4,2,1,3]输出:[1,2,3,4]示例 2:输入:head = [-1,5,3,4,0]输出:[-1,0,3,4,5]示例 3:输入:head = []输出:[]提示:链表中节点的数目在范围[0, 5 * 104]内 -105<= Node.val <= 105进阶:你可以在O(nlogn)时间复杂...
2022-02-14 15:54:15
525
5
原创 C++类与对象(中上)
类的6个默认构造函数构造函数对于以下栈类(简单模拟):定义出对象s后,首先需要调用初始化函数Init(),把对象s初始化。如果忘记调用该方法,进行一些入栈等操作,就会导致编译器报错,但是每次定义对象都要是使用该方法设置信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员 都有 一个合适的初始值,并且在对象的生命周期内只调用一次。 特性构造函数的主要任务并不是开空间创建对象,.
2022-02-12 17:20:30
540
7
原创 C++类与对象(上)
目录类的引入类的定义类的访问限定以及封装1.访问限定符的说明2.封装类对象的大小this指针面试题类的引入C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如以下代码,就可以编译通过:main函数中的st,就称为对象,以上结构体的定义,在C++中一般使用class代替。类的定义类定义的格式如下:class className{ //类体,由成员函数和成员变量组成};class为定义类的关键字.
2022-02-10 19:52:30
734
11
原创 C++函数重载
目录函数重载的概念函数重载的应用为什么C++支持函数重载,而C语言不支持函数重载的概念函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的 形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。函数重载的应用1.比如以下代码,函数名一样,而参数的类型不同,在调用的时候编译器会根据传递的参数自动进行匹配。2.在例如以下代码,我们进行编译,都可以编译成功。3.接下来看一个有趣的现象..
2022-02-06 20:34:28
689
原创 归并排序(代码+详解)
基本思想:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有 序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序核心步骤: 代码从以上图中可以看出,归并排序就是将有序的序列进行合并,从而得到一组有序的序列。所以首先给出如下一段代码,用来合并两组有序的序列:...
2022-01-27 15:58:22
10128
3
原创 快速排序(代码+详细分析)
基本思想:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。图解:假设有下列一组数据,此时规定每次分割选定当前序列最右侧的数值为基准值,那么第一次的基准值为3,分割为两个子序列后,在分别选定子序列最右侧的数据为基准值,再重复上述过程,就完成了排序。代码:分析上述过程,需要一个将数组进行分割的函数,我们只需要想
2022-01-25 17:00:02
13804
2
原创 选择排序+堆排序
目录选择排序基本思想图解代码复杂度与稳定性堆排序基本思想图解代码复杂度与稳定性选择排序基本思想每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。图解给定如下数组,排成升序:1.从五个数值中选定最大的数字5,与最后一个数值1进行交换:2.从剩下四个数值中选定一个最大的,与最后一个数值3进行交换:3.从剩下的三个数值中选定一个最大的,与最后的数值1...
2022-01-14 13:27:37
173
2
原创 插入排序+希尔排序
目录插入排序1.基本思想2.单个元素插入有序数组图解3.插入排序图解4.代码5.复杂度与稳定性希尔排序1.基本思想2.图解3.代码4.复杂度与稳定性插入排序1.基本思想 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为 止,得到一个新的有序序列。2.单个元素插入有序数组图解要把数字 3 插入到下面的数组中,使其成为一个升序的数组:int arr[5]={1,2,4,5};...
2022-01-11 15:03:51
470
4
原创 二叉树展开为链表(LeetCode)
目录1.题目2.图解加代码3.代码的简化1.题目给你二叉树的根结点 root ,请你将它展开为一个单链表:展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。示例 1:输入:root = [1,2,5,3,4,null,6]输出:[1,null,2,null,3,null,4,null,5,null,6]示例 2:输入:root = []
2022-01-07 18:20:32
1915
3
原创 另一棵树的子树(LeetCode)
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。示例 1:输入:root = [3,4,5,1,2], subRoot = [4,1,2]输出:true示例 2:输入:root = [3,4,5,1,2,null,null,nu..
2022-01-05 15:27:03
491
1
原创 翻转二叉树+检查二叉树是否镜像对称
目录1.翻转一棵二叉树。思路:图解:代码:2.给定一个二叉树,检查它是否是镜像对称的。代码:1.翻转一棵二叉树。示例:输入: 4 / \ 2 7/ \ / \1 3 6 9输出: 4 / \ 7 2/ \ / \9 6 3 1思路:...
2022-01-03 16:40:38
871
1
原创 删除链表的倒数第 N 个结点(力扣题目)
目录1.题目2.思路3.图解4.代码1.题目给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。示例 1:输入:head = [1,2,3,4,5], n = 2输出:[1,2,3,5]示例 2:输入:head = [1], n = 1输出:[]示例 3:输入:head = [1,2], n = 1输出:[1]2.思路这道题可以先遍历一遍,得到链表中的节点个数,然后在计算出要删除的节点的位置,从而删除该节点。也可以只遍
2021-12-31 14:49:59
389
原创 分割链表(面试题)
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。你不需要 保留 每个分区中各节点的初始相对位置。示例 1:输入:head = [1,4,3,2,5,2], x = 3输出:[1,2,2,4,3,5]示例 2:输入:head = [2,1], x = 2输出:[1,2]思路:定义出两个头节点(s1,s2),把值小于x的节点尾插在s1之后,把等于或者大于x的节点尾插在s2之后,最后再把两个链
2021-12-30 21:15:54
421
原创 k个一组翻转链表(力扣题目 C语言解法)
目录图示:代码:给你一个链表,每k个节点一组进行翻转,请你返回翻转后的链表。k是一个正整数,它的值小于或等于链表的长度。如果节点总数不是k的整数倍,那么请将最后剩余的节点保持原有顺序。示例 1:输入:head = [1,2,3,4,5], k = 2输出:[2,1,4,3,5]示例 2:输入:head = [1,2,3,4,5], k = 3输出:[3,2,1,4,5]示例 3:输入:head = [1,2,3,4,5], k = ...
2021-12-26 17:13:31
1471
1
原创 二叉树的构建与遍历(C语言)
目录一、二叉树的存储结构二、二叉树的遍历一、二叉树的存储结构1.顺序存储:顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空 间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺 序存储在物理上是一个数组,在逻辑上是一颗二叉树。2.链式存储二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是 链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存
2021-12-11 17:35:58
4788
2
原创 堆的实现(C语言)
什么是堆?可以简单理解为:1.堆中某个节点的值总是不大于或不小于其父节点的值;2.堆总是一棵完全二叉树3.将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。 理解了堆的概念后那么下面就来创建一个堆。假设有这样一个数组:int array[]={8,2,3,4,5,6},存储的是完全二叉树,那么:从上图中可以发现,除了根节点外,其余部分满足小堆的基本性质。因为:2<4, 2<5; 3<6。那么如何将上面的完全二叉树调整为一个小堆呢?首先,...
2021-12-06 22:09:32
895
1
原创 删除链表中重复的结点(C语言暴力破解版)
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。这是一道删除单链表中重复元素的题目,下面来进行暴力破解。思路:给两个指针slow和fast,slow用来标记当前节点,fast指向slow标记的节点后面的节点,用fast->val来和slow->val进行比较,不相等则fast直接往后走一步,如果相等则删..
2021-12-04 23:30:56
1225
原创 通讯录 代码与分析(C语言)
C语言实现通讯录,这里我使用多文件的形式,分别分为三个文件:1.contact.h 这是头文件,用来包含其他头文件和进行函数声明以及宏定义。2.main.c 主调函数,main函数的存在地方。3.contact.c 提供通讯录的各种功能函数下面来讲讲通讯录实现的基本思想,通讯录的实现肯定要用到结构体,因为一个人有很多信息,所以首先我们定义一个结构体struct person(名字可以改),用来存放单个人的信息,但是通讯录不止一个人,所以还得在定义一个结构体st...
2021-11-11 17:15:17
19486
1
原创 strstr函数的使用与模拟实现
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。比如如下代码的运行结果就是:cde#include <stdio.h>#include <windows.h>#include <string.h>int main(){ char str1[] = "abcde"; char str2[] = "cd"; char *str=strstr(str
2021-10-25 18:21:36
243
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人