自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 基于select实现socket的超时功能

今天遇到一个要求,套接字连上之后,由于在recv数据时就阻塞住了,一般会要求等待5s之后假如超时就返回失败,通过select实现了一下要求:#define BUF_SIZE 128#define RESPONSE_TIMEOUT 5int ReciveResponse(int sfd, void *out_receive_data, int receive_data_size) { if (!out_receive_data || receive_data_size == 0) {

2021-09-18 19:52:57 409

原创 图论基础——拓扑排序

拓扑排序拓扑排序所解决的问题是在一些有向图中,需要完成一些前置条件,也即走完这个点的所有前置的点才能前往该点,要得到一个顺序;这个问题需要基于入度来思考,需要一个入度数组来记录指向每个点的入度个数,当这个点的入度为0时就是这个点所有前置条件都完成了可以前往该点了;因此需要一个数据结构来保存所有入度为0的点,可以是队列,栈或者是优先队列,当然数组也可以;代码实现:由于需要以某点为起点遍历所有边所以用链式前向星来存边;采用栈的形式来保存所有入度为0的点;最后结果:拓扑排序检测有向图是否存在

2021-03-05 17:51:17 480 1

原创 图论基础——最小生成树

树、图与生成树的定义树:需要保证到达每个点只有通过唯一的路径,即每两个点间只有唯一的边,且不会存在交叉的边;图:没有限制,点与点之间可以有很多边存在,路径也可以交叉;生成树:是在图的基础上,保证每个点相连,抽象出来的新的图;由于选择路径不同,一个图可以有多种生成树;生成树必须保证图为无向图;生成树特点:节点数量和图的结点数量一致;n个结点,生成树有n-1条边;最小生成树:所有生成树中所有边的权值最小的生成树为该图的最小生成树;计算最小生成树的算法以洛谷3366题 最小生成树模

2021-03-04 12:28:49 840 1

原创 图论基础——启发式搜索

启发式搜索启发式搜索是结合广搜和最短路径思想的一种算法。广搜本质上是一种暴力的搜索算法,围绕起点将所有能走的路径全部进入队列,再根据队列依次出发进行下轮的搜索。但是广搜会有非常多的浪费搜索,与终点完全反方向的地方也会进行搜索。启发式搜索的实现而启发式搜索会在广搜的基础上增加三个条件:G-与起点的物理距离,H-与终点的物理距离,F-G和H两者之和;并且使用优先队列维护每次进行搜索的点总是优先队列中与F最小的点。代码实现:预处理node结点需要记录位置以及走过的路径步数,以及当前点到终点的距离h,由于

2021-03-04 11:45:34 1335 1

原创 图论——最短路算法

首先最短路问题不能有负环,即走一圈后的权值比出发的权值要小,不能存在这样的结构。以题目为例:①dijkstra算法(单源最短路算法,只能有一个起点,且无负权边)dijkstra算法其实是一种搜索的算法,只选择当前权值最小的路径去走,当走到每个节点时判断一下是否可以更新当前结点的权值,可以更新说明是一种更优的方案,所有更新之后并进入堆中,走完所有结点后,就可以得到从起点到达每个路径的最小权值;代码实现:首先需要保存每个结点当前的最小权值,所以结点的结构需要有当前的位置和权值,由于后面需要用堆结构去每

2021-02-26 22:55:09 447

原创 图论基础——图的存储

一、基础概念:①、图的定义:点和边的集合②、边的方向:边具有方向则为有向边,图中边有方向则为有向图;边不具有方向则为无向边,图中边没有方向则为无向图;③、边的权值:为边所有的属性,可以具象化为路径的长度,或路径花费时间、或飞机的机票价格;边可为负数。④、点的度:度为该点与几条边相连。有向图的点的度分为出度和入度,度总是为出度+入度;二、图的存储①邻接矩阵:本质上是二维矩阵,有向图的邻接矩阵的横坐标为边出发点,纵坐标为边的终点,矩阵中存的是该边权值;而对于无向图而言需要同时反向再存储一次

2021-02-24 23:07:21 256

原创 用脚本实现检测进程是否运行

直接看代码:首先执行count=ps -ef|grep server_alarm|grep -v grep,ps-ef首先查看当前运行的进程并检索(grep)正在运行的程序名称,由于grep时会自动运行一个对结果上色的进程所以需要将prep结果中含有grep字段的给反向检索也就是删除,然后判断执行这条指令之后的返回值,假如检索到也就是有确切程序在运行会返回0也就是指令执行成功,假如不为0就是指令执行失败也就是当前该进程已经终结,重启该程序并放在后台执行,而&符号是代表执行完命令并置于后台运行。

2021-01-19 14:19:38 950

原创 字符串匹配算法之哈希匹配算法

使用场景哈希匹配算法比较适合适用于多次对固定串内部匹配的算法。预备理解哈希匹配算法的原理是采用一种哈希函数将字符串映射成一个数字,之后就演化为两种方法:第一种:假如数字相同,则去遍历匹配两串;第二种:采用两种哈希函数,假如两组不同哈希映射后得到的数字相同则判断为字符能够匹配的上。第二种方法的速度快但是存在误判即将不能够匹配的上判断为匹配的上,只是若是哈希函数设计的好这种概率会非常的低。这里采用的哈希函数为:K=(C0∗Base0+C1∗Base1+C3∗Base3+...)(modP)K=(

2021-01-18 22:58:06 2219

原创 字符串匹配之Shift_and算法

Shift_and是一种时间始终稳定在O(n)的算法。这种算法首先需要将子串 t 预处理为二进制模式,举个例子如图子串为“aecaebf”就可以通过位运算通过一个数字记录下在字符串中出现的位置,比如a字母出现在第0位和第3位,则储存a字母的数组中的数字就为202^020 + 232^323 = 9,依次采用相同的方法将每个子串出现位置的二进制模式记录在数字数组中。接下来就是匹配的过程,最为重要的公式为:P=(P<<1∣1)P=(P<<1 | 1)P=(P<<1

2021-01-18 21:16:38 811 1

原创 字符串匹配算法之Sunday算法

暴力求解通常用来判断两个字符串(母串s,子串t)可以直接使用暴力求解的算法即遍历母串s,接下来依次比较子串t个位置中子串与母串是否中字符是否相等,这种方法暴力且好理解,代码如下:Sunday算法这个算法时间复杂度为O(n * m),而大部分时间都在匹配第一个字母,而Sunday算法就是对暴力求解的一种优化。首先对字串t进行预处理,找到每个字母最后一次出现的位置(这里是为了向后位移的大小尽量小),在发生不匹配时,能够直接匹配到字串t中与母串不匹配位置字母最近的同个字母,接下来再依次遍历相应位置字串,就

2021-01-18 20:24:43 372

原创 C语言编写红黑树

一、平衡条件节点非黑既红根节点是黑色叶子(NIL)结点是黑色红色节点下面接两个黑色节点从根节点到叶子结点路径上,黑色节点数量相同注:1. 第4条和第5条条件,注定了,红黑树中最长路径是最短路径的长度的 2 倍。2. 本质上,红黑树也是通过树高来控制平衡的。3. 红黑树比 AVL 树树高控制条件要更松散,红黑树在发生节点插入和删除以后,发生调整的概率,比 AVL 树要更小。二、理解层面理解红黑树的插入调整,要站在祖父节点向下进行调整理解红黑树的删除调整,要站在父节点向下进行调整

2021-01-04 20:01:11 421

原创 C语言编写AVL树

一、性质平衡条件:左右子树高度差不超过 1高度为H的AVL树包含结点数量的范围:1.5H - 2H-1(low(H) = low(H-1) + low(H-2)+ 1 ≈ 1.5 类斐波那契数列)综上:所以树高和结点数量的关系 h = logn二、平衡调整策略发生在回溯阶段的,第一个失衡节点处理解平衡调整策略的关键在于:分析清楚四种情况下,ABCD 四棵子树树高的关系LL,大右旋LR,先小左旋,再大右旋RL,先小右旋,再大左旋RR,大左旋三、代码实现插入和删除以后

2021-01-04 17:01:29 147

原创 C语言编写二叉排序树

一、性质左子树 < 根节点右子树 > 根节点中序遍历的结果,是一个有序序列二、插入操作插入的新节点,一定会做为叶子结点三、删除操作删除度为0的节点,直接删除删除度为1的节点,把『孤儿子树』挂到其父节点上面去删除度为2的节点,可以转化成删除度为1的节点注:插入顺序会影响最终的树形结构不同的树形结构,查找效率不同平均查找效率:节点查找次数的期望值,总次数/节点数量,假设每个节点等概率的被查找代码实现:二叉树的结构体,获得新

2021-01-04 16:55:01 230

原创 C++ 广度优先搜索

广度优先搜索和一条路走到底走不通再回头的深度优先搜索不同的是,他按层进行搜索的,会按照设定好的方向例如[右, 上, 左, 下]的逆时针方向,先将四个方向的下一个点能走的全部放进一个队列种,然后按照队列的顺序依次走下一层,所以广度有点搜索不仅可以判断连通性的问题还可以判断到达终点需要的步数;同样以迷宫S. . .##. .##. .T. . .为例子来进行广度优先搜索:首先由于需要用到队列所以需要队列的头文件,依然是字符地图,方向数组以及地图大小和起始点,这里为了判断需要的步数所以定义了一个结构

2020-11-18 17:47:33 633

原创 C++ 深度优先搜索

深度优先搜索是指按照一定的方向不停向更深层搜索,只有当走不通时才会回到回溯到上一层,按照下一个方向进行搜索:举个例子:S. . .##. .##. .T. . .这样一个4*4的迷宫,其中’ . '是可以走的路,‘ # ’是墙壁,S是起点,T是终点,很明显这是可以走的通的。但是按照深度优先搜索的思路,首先需要规定一个方向数组也就是首先到达一层时会按照设计好的方向去尝试,假如尝试成功也就是走的通的话就在这个点进入下一层。假设规定的规定的方向是[右, 上, 左, 下]按照逆时针的优先级进行方向的判定

2020-11-18 17:17:01 728

原创 二分查找的几种模式

二分查找是一种非常基础的搜索方法,也具有固定的模板。首先是朴素的二分查找方法,也就是在一堆排好序的数组中搜索一个数字(没有排好序也可以,可以自己手动排序):首先是给定数组length[],数组a的长度n,以及查找的数字m,这时候只需要进行一下步骤就可以,这里的写法比较多种多样,但是要是理解了也万变不离其宗,首先是左右指针分别指到首位位置,之后进行二分循环,循环条件这里是写法可以不同的地方,但是写左边小等右边最后的结果一定是会出现左边right,右边left的结果,这里可以用来解决重复数的问题,假如一个数

2020-11-03 22:05:19 269

原创 C语言 线性筛

在上一篇讲到素数筛,素数筛的时间复杂度为O(NloglogN)其中loglogN是由在筛去数是有一些数被筛了多次例如,18被2和3和6和9各筛一次,而这多余的就是来自于重复筛的步骤。而这存在这优化的方式就是线性筛。线性筛的条件是一个合数M必须由最小素数因子P和最大因数N筛去,而其中P也必须不超过N的最小素数因子。举个例子,最大因素25可以筛去225=50,325=75,525=125但是7*25就不行,因为作为虽小素因子7是大于N(25)的最小素因子5的。基于这个性质就可以完成线性筛的过程。首先依然是定义

2020-10-26 21:21:32 653 1

原创 C语言 牛顿迭代法求解根值

牛顿迭代法是一种数值分析的方法,所以用这种方法求出来的方程的根值是数值解,也就是通过迭代的方法找到近似解。首先牛顿迭代的公式可以通过泰勒一阶函数展开得到即:f(x) = f(x0) + f(x0')(x - x0);由于是求方程的根即令f(x) = 0可以得到 f(x0) + f(x0')(x - x0) = 0;变形一下得到 x = x0 - f(x0')/f(x0);而将x0变成xn的话就可以得到迭代公式:x(n+1) = x(n) - (f(xn') / f(n));并且由于求的是根值,所以只要

2020-10-26 20:05:47 3821

原创 C语言 素数筛

求n值范围内的所有素数,这种题可以用素数筛的方法来做。以100为例,首先定义一个大于100的数组来进行100个数的储存。由于素数是从2开始的,所以需要从2开遍历整个数组,由于数组是定义在全局区所以会自动初始化为0,规定以数字0代表该下标数为素数,而数字1代表该下标数不是素数,首先2是素数,而接下来将2在100以内的所有倍数全部标记为1,而将prime[0] 作为纪录总共有多少个素数的计数器,并且将数组的前几个数重写入素数,所以这个列表有三个作用:1.代表着所有数是否是素数的标记表;2.prime[0]

2020-10-26 19:35:04 758

原创 C语言 编写二叉搜索树

二叉搜索树的最大特点是由根节点进入后左节点的值均小于根节点的值,右边节点的值均大于根节点的值。并且二叉搜索树还有重要的特点就是中序遍历的二叉搜索树会的得到一个严格升序的数组。首先需要编写节点以及代表头节点树的结构体:创建一个插入函数,首先将需要放入的值包装成可以放入的节点。假如进入的节点本身就为NULL节点的话,直接将放入值的节点放入根结点处。假如进入的根节点不为NULL的话与其中的值进行比较,比根值大就进入根的右侧,比根值小就进入根的左侧。同时假如下一个节点是NULL的话直接将需要插入的值插入,而

2020-10-19 22:02:19 158

原创 C语言 编写线段树

线段树同样也是一个比较冷门的数据结构,一般用于计算区域和,或者在修改某一个或几个节点的数据时,计算区域数据和。首先线段树的特点是树的叶子全是数组中的数,而往上的节点都是相应子节点的和。首先需要对数组创造相应的树结构。其中node为0也就是根节点,start和end指的是需要创建树的数组的起始和终点位置。而整个函数的思路为,mid为起点和终点的中点,根节点代表[start,end]的元素和,而它的两个子节点就是[start,mid]和[mid+1,end],同时接着往下走,把数组进一步进行划分,由于用的是

2020-10-05 20:16:49 312 2

原创 C语言 编写并查集

并查集是一种比较冷门的数据结构,通常用于查找无向图是否存在环。在做无向图是否有环的时,一般是用深度或者广度优先搜索遍历一遍,但是并查集提供了另一种思路。首先需要用一个parent数组来记录该点的连接点,通过这个数组的一个位置来寻找它的最父辈的点。首先按照数组大小新建一个parent数组并将其初始化为-1,假如搜索到一个点的parent值为-1则它就是最顶点的一个。第二个就是搜索函数,输入一个点去寻找它的根节点,通过一个循环函数,达到目的。最后就是合并函数,将两点输入进来,通过搜索函数搜索,假如两点

2020-10-05 16:05:49 332

原创 C语言 手写快速排序

c语言中自己本身就存在快速排序的函数qsort()。但是也会有一些问题是建立在快速排序的变形比如说按照一定的规则排序,或者说是链表的快速原地排序,这就需要对快速排序的方法进行一些改进。这是一个例题,输入一串数,对这些数按照绝对值大小进行排序。首先用连续的scanf将数字串输入进数组中,终止通过EOF在linux中是ctrl+D。然后排序通过函数quick_sort实现。这是快速排序的核心。首先是整体上的结构,快速排序的一次完成是首先确定一个“枢纽值”,用双指针一个从头开始寻找,一个从尾部开始

2020-09-29 23:40:14 490

原创 C语言 编写简单哈希表

经常在做leetcode的时候会用到哈希表进行存储数据然后进行搜索,所以就介绍一下C语言哈希表的简单实现。首先要了解一下哈希表的具体结构,哈希表简单的来说就是数组加链表实现较为快速的数据搜索。具体就是通过一定的函数(哈希映射)确定存放数组的位置,假如由函数确定出几个数存放在数组同一位置的话就由链表由存放次序存放。搜索一个数的时候是需要通过函数计算出数组的存放下标,然后按照链表依次搜索,这样的效率会比遍历整个数组快速的多。编写一个哈希表首先需要确定一个链表结构的结构体,结构体里包括需要防放入的数字以及指向

2020-09-21 22:54:14 653

原创 C语言 数组的快速排序qsort

通常会遇到将数组中元素排序的问题,那可能会有很多方法去解决这个问题例如冒泡排序,快速排序等等,但是实际上C语言中本身有一个自带的快速排序的函数qsort()。首先来看一下qsort()函数的定义:qsort(void * base, size_t a, size_t b,int(cmp)(void * , void * )); 其中第一个参数void *base是需要进行排序的数组,void代表数组可以是任意格式,可以是int型,char型甚至是自定义的结构体格式;size_t a是需要排序数组的

2020-09-13 15:04:23 1582

原创 C语言 字符数组初始化以及memset函数

首先为什么要初始化数组:假如创建了一个没有初始化的数组,里面其实各个位置是含有值的,举例: char a[10]; char b[] ="duiao1222"; strcpy(a,b); 非常简单的函数就是让a为b的一个复制数组,但是真的去输出a的时候,结果并不是这,这是因为a并不是一个全为0的字符数组。 最为简单的初始化方法就是char a[10] = {0};就可以将所有位置初始化为‘\0’。 当然可能会有一些情况导致这种方法不能初始化,或者字符数组是动态创建的,没有一个可以进行{0}的.

2020-09-07 19:27:53 2040

原创 C语言 取绝对值函数abs()使用及注意事项

取绝对值函数abs()包含在<math.h>或者<stdlib.h>中,函数原型为int abs(int n);也就是说对于整型数n放入函数中返回一个正整型|n|,用一个整型变量接收即可。这个非常好理解,因为是比较基础的函数且取绝对值的行为也不陌生。但是有需要注意的地方就是,由于int型的变量范围为(-2^31 - 231-1),其中就出现了一个数字的差距,假如放入函数为-231,但对其取绝对值后为2^31就超出了整型接收的范围,得到的数字就可能出现偏差,而这种情况只能将其单独

2020-08-31 22:22:12 6786

原创 二叉树的前中后序遍历——递归以及Morris迭代算法

对于二叉树而言首先需要建立一个二叉树结点的结构体,因为对于每个节点而言都是相似的结构:(1)节点里的数据;(2)指向左节点的节点指针;(3)指向右节点的节点指针;而同时左右指向的又是相同的节点结构,所以需要建立这样的结构体;当然其中的数据可以是更复杂的结构。而对于一个二叉树而言,所谓前中后顺序遍历,其实只是根据遍历时根所在的位置来决定,前序代表:根-左-右;中序代表:左-根-右;后序代表:左-右-根。而一个二叉树可以看成是一个由很多小节点组成的大的节点,所以所有的节点都可以按照一个顺序进行遍历。

2020-08-21 20:57:00 397

原创 C语言 编写Vector方法

Vector是一个单口进出的数组结构有一点像栈的结构。首先建立这样一个结构体,里面包含一个数组以及一个位置标记,数组来存放进入的元素,标记指向尾部最后一个没有存放东西的数组位置。当然数组元素可以自定义为任何格式,甚至也可以是vector套vector类型。例如是这样就是数组里面装着数组。常用的三个方法:初始化,进vector和出vector。其他像检查vector长度可以自己尝试编写。...

2020-08-19 19:36:55 2240 2

原创 Leetcode 733题 广度优先搜索

题目如下:题目简介:接收一个大小为[n][m]的数组,其中数组有颜色oldcolor(数字表示),没颜色的用0表示,需要从(sr,sc)位置开始将颜色oldcolor变成newcolor,但是假如oldcolor周围均为0就不用渲染。很明显是一个广度优先搜索进行遍历数组的题目,广度优先遍历的需要有两点①队列来进行记录当前位置以及当前元素,以及下一个位置的位置以及元素;②需要对当前位置四周进行判断是否是有颜色,以及该位置有没有走过。首先定义结构体point纪录当前位置以及颜色;定义一个队列,其中数

2020-08-18 19:43:19 175

原创 c语言 队列方法的编写

队列的特点是先进先出,就像排队买票一样,就结合排队买票的特点编写实现队列的方法。首先队列的实现需要三个元素:(1)排队通道,通常用数组来表示;(2)队首的标记,用来出队列使用;(3)队尾的标记,用来加入元素使用;完成上述工作需要用结构体定义队列的三个初始属性:按照队列的特点需要完成一下几点:(1)队列初始化,由于定义的结构体里只是定义了属性,而没有定义属行一开始该是多少所以需要初始化一下;将首位标记均初始化为0(2)进队列:进队列需要将新的元素放进data[]数组中,并且将尾部标记向后移

2020-08-17 22:07:36 681

空空如也

空空如也

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

TA关注的人

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