自定义博客皮肤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)
  • 收藏
  • 关注

原创 01数据结构-串和KMP算法

串是由0个或多个字符组成的有序序列。串中字符的个数称为串的长度,含有0个元素的串叫空串。在C语言中,可以用如下语句定义一个名为str的串。C语言定义了’\0’作为字符串的技术标志,但在描述串的长度时,需要通过扫描整个串才获得,时间复杂度为O(N),不如额外定义一个变量专门来存储串的长度,这样求串的长度的时间复杂度为O©的操作了。不同的编程语言,是否用’\0’作为串的结束标语,是没有定论的,可以通过length来约束空间的长度也会更通用。

2025-09-19 17:25:57 855

原创 01数据结构-Floyd

之前咱们讲图的最短路径的算法的时候,咱们用的Dijkstra算法,他是单源点且路径不能是负数,例如:我们知道成都到达州的最短距离,但不能知道郑州到北京的最短距离,实际上我们可以对图中的每个顶点都使用Dijkstra算法,这样虽然也能求,但是显得比较麻烦,今天咱们来学习图中的另外一种算法Floyd算法(也和咱们的的动态规划有关)

2025-09-17 17:03:29 610

原创 01数据结构-01背包问题

当我们要在背包容量为2的情况下放入物品id1的时候,我们要么不放入1,此时最优结果F(0,2)是图中橙色区域对应部分,要么放入1,此时最优结果是放入1后1的价值加上背包容量减去1的重量的背包容量作为F()的参数,即F(0,0)图中绿色部分,明显0+10>6,所以此时我们填写的是10。如图,同理当背包容量为0的时候,1号和2号物品也放不进去,当背包容量为1的时候,此时我们可以有两种选择,一种是选择不放1,那么最优值是F(0,1),如果放入物品2,发现物品2重2放不进去,我们取最优解,肯定是F(0,1)。

2025-09-14 18:44:20 1021

原创 01数据结构-初探动态规划

在学习动态规划时切忌望文生义,因为其名字与其思想关系不大,你可以自己想一个记住其思想的名字,例如:递推公式法,状态转移方程法等等。与其说动态规划是一个算法,还不如说是解决问题的方法论,动态规划的一般形式就是求最优值,比如最长公共子序列,最大子段和,最优二叉搜索树等等。

2025-09-13 16:04:31 1030

原创 01数据结构-B树练习及B+树特点

在B树中的一个节点中的数据包含数据,key和指针域,通常我们认为这会使得节点内存放的数据量会变少,我们知道一个B树中的一个节点就是一次磁盘IO,假设一个节点能存512个字节数,我们数据一般都会占大头,假设一个数据中的数据,key和指针域占有256个字节,这样一个节点仅可以存放2个数据量,这样树的高度显得没有那么“矮胖”,这有点违背B树设计的初衷。这个重复出现的元素充当的是“路标”或“分隔符”的关键角色。2.依次将关键字5,6,9,13,8,2,12,15插入初始为空的4阶B树后,根节点中包含的关键字是()

2025-09-12 14:34:05 910

原创 01数据结构-B树

磁盘的物理结构你可以理解为一个一个磁道(类似于操场跑道一样),每个磁道,我们都有一个轴,这个轴可以伸长,我们读一个磁道的时候会有一个扇面,如图我们称为block(块),意味着,磁盘中的“地址”不像内存那样是连续的地址,而是一个块号,在磁盘中有个磁盘控制器,当操作系统请求读取一个逻辑块,磁盘控制器定位到该块对应的起始扇区,读取这个扇区及后续连续的几个扇区,将数据整合后返回给操作系统。而这一块就不是一个字节了,我们大部分都认为这个块的字节大小是512B。

2025-09-10 16:03:14 1324

原创 01数据结构-红黑树

我们来回顾一下搜索树的“进化过程”二叉搜索树的特性,二叉树,左子树的值小于根节点的值,右子树的值大于根节点的值,中序遍历的情况下是有序的序列,缺点是在特殊情况下,树可能会退化成单链表平衡二叉树的特性:二叉树,左子树的值小于根节点的值,右子树的值大于根节点的值,中序遍历的情况下是有序的序列,树的高度可控,优点是静态特性最优,树一旦构建完成,查找时,效率最高,缺点是动态特性稍差,插入,删除节点时平衡因子容易失衡,需要频繁进行旋转操作。

2025-09-01 20:52:26 825

原创 01数据结构-查找

在一堆数据中,找某一个特定的数据就是查找。查找分找到和没找到,如果我们是顺序存储的数据元素,找到了的话一般就返回该元素的索引取值范围可以是[0,n-1],没有找到的话就返回-1,但是这样有一个小问题,负数的表示既要表示数字又要表示符号,我们返回的范围就变少了,所以很多时候真正存储的时候我们索引的取值范围为[1,n],返回的时候返回0。如果是链式存储,找到了我们就返回节点首地址,没找到我们就返回NULL。

2025-08-27 10:12:55 582

原创 01数据结构-归并排序和计数排序

归并排序,其排序的实现思想是先将所有的记录分开,然后两两合并,在合并的过程中将其排好序,最终得到一个完整的序列。由于使用到的递归思想,我个人认为也可以叫递归排序。归并排序非常适合大数据排序,大部分数据都在磁盘上,我们可以用归并排序拆分,我们拆成可以在内存中保存的n个有序区间,往回写到硬盘里,再进行合并这几个有序序列的时候工作量就变小了。

2025-08-23 17:25:30 1044

原创 01数据结构-堆排序

数据结构中的堆是一种结构,C语言的堆是空间管理的程序员malloc,free的空间,两者没多大关系。

2025-08-21 11:21:43 961

原创 01数据结构-交换排序

算法思想冒泡排序是最简单的排序算法了。冒泡排序通过不断地比较两个相邻元素,将较大的元素交换到右边(升序),从而实现排序。那我们直接看例子。我们对数组 [5,1,4,2,8,4] ,采用冒泡排序进行排序,注意这里的两个 4 的颜色是不同的,主要是为了区分两个不同的 4 ,进而解释冒泡排序算法的稳定性问题。第一轮冒泡排序:第一步:比较 5 和 1 ,5 > 1,则交换 5 和 1 的位置:第二步,比较 5 和 4,5 > 4,交换 5 和 4 的位置:第三步:比较 5 和 2 ,5 > 2,交换 5

2025-08-18 18:23:20 824

原创 01数据结构-插入排序

我们前面讲的都是数据的结构,我们数据有很多元素,那这么多的元素我们该如何去组织呢?线性结构还是非线性结构呢?组织完数据中的元素后我们需要对这些元素做一定的处理,主要的处理方案就是排序,查找。

2025-08-17 19:17:21 1154

原创 01数据结构-关键路径

我们在写拓扑排序的时候提到,拓扑排序是关键路径的基础,那么为什么这么说呢?在此之前我们看一些简单但很重要的概念。

2025-08-16 12:31:56 798

原创 01数据结构-拓扑排序

如图2,我们用邻接表来存图,创建一个一维数组表示顶点的入度值,初始化时所有的入度值都为0,在遍历邻接表的时侯,例如0能出到1,2,3,就给顶点1,2,3的入度加1。1能到2,4就给2,4顶点的入度加1,一直到遍历完所有顶点,就算时把这个图的所有顶点的初始时的入度值计算好了。例如:一个项目包括A,B,C,D四个子部分来完成,并且A依赖于B和D,C依赖于D,现在要指定一个计划,写出A,B,C,D的执行顺序,这时就可以用到拓扑排序,它就是用来确定事务发生的顺序的。重复上述操作,一直处理完所有的顶点。

2025-08-15 11:46:22 810

原创 01数据结构-最短路径Dijkstra

今天我们主要看一个最短路径算法,迪杰斯特拉算法(Dijkstra Algorithm)。这个算法的主要运用就是计算从某个源点开始到其他顶点的最短路径的算法。什么是最短路径,什么又是源点,还有最短路径算法有什么用呢?我们来一个一个的看基础概念Dijkstra算法是荷兰计算机科学家艾兹赫尔·迪杰斯特拉于1956年提出的​​单源最短路径算法​​,用于解决带权有向图或无向图中从起点到所有其他节点的最短路径问题,核心思想是​​贪心策略​​,逐步扩展最短路径树。

2025-08-14 12:23:15 781

原创 01数据结构-Prim算法

Prim算法在找最小生成树的时候,将顶点分为两类,一类是在查找的过程中已经包含在生成树中的顶点(假设为A类),剩下的另一类为B类。对于给定的连通图,起始状态全部顶点都为B类。在找最小生成树时,选定任意一个顶点作为起始点,并将之从B类移至A类;然后找出B类中到A类中的顶点之间权值最小的顶点,将之从B类移至A类,如此重复,直到B类中没有顶点为止。所走过的顶点和边就是该连通图的最小生成树。(简单对比一下:上一节课的Kruskal是找边,这几棵的Prim算法是找顶点。

2025-08-13 12:26:05 1215

原创 01数据结构-Kruskal算法

在含有n个顶点的连通图中选择n-1条边,构成一颗极小的连通子图,并使该连通子图中n-1条边上的权值之和达到最小,则称其为连通网的最小生成树一个连通网的生成树是一个极小的连通子图,它包含图中全部的n个顶点,但只有构成一棵树的n-1条边连通图和它对应的生成树,可以用于解决实际生活中的问题:假设A,B,C和D4座城市,为了方便生产生活,要为这4座城市建立通信,对于4个城市来讲,本着节约经费的原则,只需要建立3个通信路线即可,如图1右边。

2025-08-12 12:28:12 895

原创 01数据结构-十字链表和多重邻接表

邻接矩阵:很全面包括带权/无权,有向/无向都使用,但是对于顶点较多边很少的稀疏图来讲,空间利用率低。所以人们提出了邻接表邻接表:主要用于存有向图,正邻接表计算出度简单,但计算入度难,逆邻接表计算入度简单,但计算出度难,要想计算入度出度都简单,人们就把正邻接表和逆邻接表结合起来了,就有了我们今天讲的十字链表十字链表:主要用于存有向图,计算出度,入度简单,代码量可能会多一点。

2025-08-11 19:20:59 1230

原创 01数据结构-图的邻接表的深搜和广搜代码实现

邻接表的存储逻辑在《01数据结构-图的概念和图的存储结构》链接:中有详细介绍,这里放一张简单的图。图1。

2025-08-10 12:12:26 925

原创 01数据结构-图的邻接矩阵和遍历

中的参数,第一个传的是哪一个图,第二个传的是一个字符串数组用于初始化MatrixVertex中的char *show,第三个传的是约束实际的顶点数量,第四个传的是是否有向,第五个传的是每条边的权重,写了一个数组来存已经访问过的顶点,由于类似于树的先序遍历,所以函数进来就要访问,然后把传入的顶点设为已被访问,进入for循环从0号顶点一直遍历到graph->nodeNum,判断有哪个顶点与他右边并且未被访问,如果找到进入递归,一直递到第一次传入的顶点v找遍graph->nodeNum这么多顶点,退出递归函数。

2025-08-09 19:17:02 707

原创 01数据结构-图的概念和图的存储结构

在线性表中,每个元素之间只有一个直接前驱和一个直接后继。在树形结构中,数据元素之间是层次关系,并且每一层上的数据元素可能和下一层中多个元素相关,但只能和上一层中一个元素相关。但这仅仅都只是一对一,一对多的简单模型,如果要描述多对多的复杂关系就需要图数据结构了。

2025-08-08 19:15:59 948

原创 01数据结构-哈夫曼树

如图4我们先从第9号元素开始填充表,先遍历前8个节点的weight找到数据中weight最小的两个元素A,G,让他们构建一个父节点,这个父节点的权值为两个数据的出现次数之和,再感觉构建出来的填写对应的parent,lchild,rchild,在构建9这个父节点的时候我们再遍历前八个元素,填写节点信息,此处应该把A和G的parent改为9,9的权值改为8,lchild改为7,rchild改为1(我们通常把出现次数少的放左边),parent我们暂定为0,,9后构建完成后,我们继续构建10号节点。

2025-08-07 19:22:28 1177

原创 01数据结构-并查集

树的基本查找我们已经讲完了,后面高阶搜索树我们后面再说,先来看树的两个应用,一个是并查集,一个是哈夫曼树,今天呢我们先讲并查集。并查集是一种非常精巧而实用的树形数据结构,他主要是处理一些不相交集合的合并和查询的问题。不相交集合,顾名思义,就是两个集合的交集为空集的一些集合。比如1,3,5和2,4,6,他俩的交集为空集。就是不相交集合。像2,3,5和1,3,5就不是不相交集合。使用并查集时,首先会存在一组不相交的动态集合 S={S1, S2,⋯,Sk},一般都会使用一个整数表示集合中的一个元素。

2025-08-06 18:21:08 1041

原创 01数据结构-平衡二叉树

前面我们介绍了二叉查找树,假设我们最开始送进去的序列就是有序的,那么会造成树往一边倒,如图1,树退化成了单链表,此时查找效率跟我们没有树的时候效率是一样的。那怎么在二叉搜索树的基础上让我们的高度可控,这就是我们今天增加的约束,增加完这个约束后就是我们今天讲的二叉平衡树。图1。

2025-08-05 10:37:14 1047

原创 01数据结构-时间复杂度和空间复杂度

⼀般来说,解决问题的⽅法不⽌⼀种。我们需要学习如何⽐较不同算法的性能,并选择最佳算法来解决特定的问题。⼀个算法的好坏,我们可以从时间和空间两个维度去衡量。执⾏时间越短,占⽤内存空间越⼩的算法,我们认为是更优的算法。并且,⼀般分为两个阶段,⼀是算法完成前的理论分析,⼆是算法完成后实际分析。「理论分析」:这种算法的效率分析是通过假设所有其他因素,如处理器的速度等是恒定的,对算法的实现没有影响。

2025-08-03 21:31:24 957

原创 01数据结构-二叉搜索树

二叉搜索树是在前面二叉树的基础上又增加了几个约束条件,没有约束的树对我们来说没有什么意义。不能解决什么问题,只能解决存储行为,为了解决进一步的需求,人们又在二叉树的基础上增加了几个规则约束。这棵树我们在工程中很少会用到,但是我们后面讲的很多树例如平衡树,红黑树。都是以这棵树为基础。大家可以看一下这个网址,里面包含了我们一些常规的难理解的一些算法的动图:链接:如果他的左子树不空,则左子树上所有结点的值均小于它的根结点的值。若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。

2025-08-03 20:09:29 961

原创 01数据结构-二叉树的线索化及实现

如图1:现有一棵结点数目为n的二叉树,采用二叉链表的形式存储,对于每个结点均有指向左右孩子的两个指针域。结点为n的二叉树一共有n-1条有效分支路径。那么,则二叉链表中存在2n - ( n-1 ) = n + 1个 空指针域那么,这些空指针造成了空间浪费。图1当对二叉树进行中序遍历时可以得到二叉树的中序序列。如图所示二叉树的中序遍历结果为DBEAC,可以得知A的前驱结点为E,后继结点为C。

2025-08-01 19:06:04 1110

原创 01数据结构-二叉树的深度广度遍历

上节课我们学习了深度遍历和广度遍历的逻辑,这节课我们来学习一下代码怎么写,并补充非递归实现深度遍历的方法。建议结合上节课的逻辑自己实现一遍代码。

2025-07-31 19:36:55 706

原创 01数据结构-二叉树的深搜和广搜概念及逻辑分析

所以这个时候就遇到了一个矛盾,处理节点的逻辑太慢了,发现节点的逻辑很快,因为当发现一个新任务的时候,往下再处理新的任务会遇到两个任务,但我们只能一次处理一个。,A的左边都是A的左子树的节点,A的右边都是右子树的节点,也就是说如果我们能在先序确定一个根,那么再根据中序遍历我们就能确定以这个根为根节点这棵树,A看完确定左右后我们再来看先序遍历中的B,发现如果以B为根节点中序遍历中在B和A之间,D和C只在B的右边,B左边为空,在图6中B的左边确实为空,依次类推,我们可以得出一个结论,进入子函数1的第四句话。

2025-07-30 22:02:10 966

原创 01数据结构-树及树的存储

从今天开始学习树,研究数据结构我们是从两方面来研究的,一是逻辑结构,一是存储结构,在逻辑关系中当元素比是1:1时,我们研究的时表结构,从今天开始元素间的关系比时1:n时,即任意一个元素往后看有n后继元素,而这n个后继元素的只有一个前驱,这种结构在物理社会中叫层级结构,比如电脑的C盘下的哪个文件,这种目录结构叫做目录树,这种层级结构就叫树。树在存储的时候也有顺序存储和链式存储两种方式。

2025-07-30 12:19:23 1117

原创 01数据结构-顺序队列和链式队列

队列是我们线性结构的最后一个结构,我们依旧采用基本结构+约束来介绍队列。我们今天要讲的约束是插入,删除分别在两端进行。为什么我要单独封装队头和队尾成结构体,因为在传递函数参数的时候我传结构体指针的时候可以改变结构体内部的值,而且单独封装节点和维护这些节点的链表头,能让代码更加美观不繁琐,由前面我们讲的我们需要一个头节点/头指针来存这些节点的第一个元素的地址方便我们操作的道理,这里也需要单独封装rear和front,还能在里面加元素个数count和对应数据结构的名字。

2025-07-29 23:20:41 808

原创 01数据结构-顺序栈和链式栈

我们讲的数据结构主要讲两方面:一方面是逻辑结构另一方面是存储结构,一般先分析问题的时候,先考虑逻辑再考虑用什么存储方式来落地,在逻辑结构中元素和元素1:1时,我们就认为完成了一个表:元素和元素1:1的设计,这个表在存储结构的时候有顺序表,链式表,随着我们学习数据结构越深入,越没有约束的结构越没有意义,反倒是在最初的结构上增加约束条件,我们用得还比较多,后面我们学树和图都是这样。

2025-07-29 18:04:34 941

原创 01数据结构-双向循环链表及实现

今天我们来写链表当中的最后一个结构:双向链表。这里我直接讲一下最常用的链表:双向循环链表。之前写的单向链表大家可以想一下有个什么样的缺点?这个缺点很明显,开弓没有回头箭,一旦往后走了就再也回不去了。在工程中,如果没有特殊情况,一般也不会用单向链表,因为很不灵活,反倒用双向链表,很灵活,往前走也行,往后走也行。在双向链表插入,删除中我们不再需要找到前一个节点,找到自己的节点即可。在C++STL中有个数据结构叫list,这个list就是我们今天讲的双向循环链表。

2025-07-28 20:41:53 962

原创 01数据结构-单向循环链表及带头指针的链表

单向链表插入,删除核心:找到前置节点 p插入:new_node->next=p->next;删除:tmp=p->next;free(tmp);带头结点的单向链表的坏处:需要一个额外的节点来作为头节点,这会增加内存的使用。虽然这个开销通常很小,但在某些对内存使用非常敏感的应用中,这可能会成为一个问题。

2025-07-27 18:39:19 1059

原创 01数据结构-单向链表的操作及实现

图2看下面这种。

2025-07-26 09:38:53 663

原创 01数据结构-顺序表的实现

内存里有成两个区:栈区和堆区。局部变量放在了栈空间上,为什么栈不具备动态性呢?下面来看这一个例子:假设有一个fun10()函数里面有数组a[5],b,*p。如果数组a可变,b空间内的值会导致越界访问了,这样后续处理逻辑上会出问题。在栈上申请空间的时候要明确指出大小,编译器在编译程序的时候会根据代码进行空间的管理,它的效率会很高,因为不存在动态性,完全是在编译的时候了清楚内存的访问行为了。堆区空间怎么访问?在栈上存放你想要存的堆区中的地址,用一个变量间接存放堆区中的地址。

2025-07-24 15:30:50 855

原创 01数据结构-数据结构概述及顺序表逻辑

C语言编程的目的是在内存上,管理空间,实现对空间的读写如何把空间构造成物理世界的逻辑,就需要定义高效的结构进行处理数据结构就是讨论用什么逻辑结构表示物理世界,用什么存储结构使得计算机处理起来更方便,更有效在计算机内存中,顺序表是以数组的形式保存的线性表。也就是一组地址连续的存储单元依次存储数据元素的线性结构。根据对这段空间的操作,可以使用静态分配和动态分配的策略,对于动态分配,需要考虑空间的扩容情况。我们会先申请一段连续的内存空间,然后数据依次存入内存当中,中间没有一点空隙。

2025-07-23 17:42:54 971

原创 数据结构前导课-3 C语言模块编程和多文件

是 CMake 中的一个命令,用于将一个子目录添加到构建过程中。这个命令允许你在项目中组织多个子项目或模块,并在主 文件中引用它们。这是因为windows终端读码方式是gbk,而编程时的文件编码时编码方式是UTF-8,所以输送到终端时会乱码,将文件编码改成gbk即可。模块化背后的原理:每个.c单独编译成一个.o,多个.o链接生成一个可执行文件。add_executable()是 CMake 中的一个命令,用于定义一个可执行文件目标。

2025-07-22 10:05:08 775

原创 数据结构前导课-2 C语言内存管理

本次数据结构课程的代码是用clion写的。

2025-07-21 11:55:38 867

原创 数据结构前导课-1 C语言语法概述

不管学什么语言都要学到数据类型,其实在早期数据类型,就是我们如何在内存上分配空间的一个模具,你可以想象计算机在内存一个字节一个字节存储,但到了软件如果一个字节一个字节的访问会显得不灵活,比如要管理一个人肯定不止用一个字节,所以建议使用统一的空间,例如一次性分配四个字节。软件为了更好的管理内存,一次性分配多个字节给一个对象使用,怎么对对象进行访问呢,需要一个模具,堆内存的管理就更加方便,这个模具的大小就叫数据类型。模具不能随便乱搞,所以基本数据类型就来了。

2025-07-20 18:00:33 611 1

空空如也

空空如也

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

TA关注的人

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