自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 数据结构---排序

肯定是能的,如果我们只有少数的顺序需要调整,大部分的顺序都是正确的(例如{2,1,3,4,5,6,7,8,9})这样的情况就会浪费很多的时间。我们先说在构造大顶堆的过程中,我们定位的结点下标是表长的一半,如果你自己动手就会发现我们的结点的总个数的一半总会在树的倒数第二层出现,这时就满足我们上述所说的从叶结点的根结点开始进行对比。的选取是非常关键的,其实至今我们对增量的选取并没有一个太好的方法,唯一确定的是增量序列的最后 一个增量值必须等于1,由于记录是跳跃性的所以希尔排序的时间复杂度其实是不固定的。

2025-12-30 20:15:20 1247

原创 数据结构---哈希

为了做到这一点,通常我们都是将散列表的空间设置得比查找集合大,此时虽然是浪费了一定的空间,但换来的是查找效率的大大提升,总的来说,还是非常值得的。如果不相等就继续向后直到都遍历完或者遇到了空位置,这里的空位置其实是一个特殊数据,因为我们插入时是向后进行的,所以如果表中有寻找的数据遇到空肯定会插入,而没有我们要寻找的数时就不会插入就会留下空位置。散列函数的好坏直接影响着出现冲突的频繁程度,不过,由于不同的散列函数对同一组随机的关键字,产生冲突的可能性是相同的,因此我们可以不考虑它对平均查找长度的影响。

2025-12-27 21:33:37 923

原创 数据结构---AVL树

但是是什么原因造成这种情况的呢?我们仔细观察之前的旋转操作和上面的旋转操作的BF就能发现,之前的旋转操作时前后结点的BF值得单位都是一样的,同为正或者同为负。说明原本的左子树就比右子树高,而现在仍然在下面插入了结点引起了不平衡,就应该进行左平衡旋转处理(与上面左平衡旋转提到的形式类似)。于是我们就解决了我们理论上的AVL树在创建中中可能遇到的所有问题,接下来的步骤按照上面的方法就可以将整个树创建完整并且平衡。再往下就是进入右子树继续往下的情况了,与上面左子树的情况是类似的,所以这里也就不再详细的说明了。

2025-12-25 16:36:01 1408

原创 数据结构---二叉排序树

再往下就是 q 和 p 所指的若不为同一个结点也就是说被删除的结点的子树高度大于一,也就是通过了 while 的树,这时就让 q 的右子树替换为 s 的左子树也就是删除 s 所指的结点。当然是被删结点的子树高度为1时,这时我们要删除被删结点的左子就让其所指为空,也是 s 的左子。接下来看插入函数,经过之前的数据结构的插入的过程,现在的插入也都是相同的。查找函数还是比较简单的,如果你对二叉树的部分比较熟悉的话可以看出来遍历的过程和结构,对我们理解还是很简单的,只有在继续往树下面进行遍历时的条件判断值得注意。

2025-12-23 20:19:02 597

原创 数据结构---简单查找

接下来看代码和具体的过程。很明显折半查找还有一个问题就在于无论什么情况都是从中间开始的,而生活中有时候我们是清楚大概位置的查找,这时的折半查找就显得慢了一些。顺序表查找又叫线性查找,是最简单的查找方式,即从表中的第一个一直到最后一个的过程,若中间找到了目标值就停下。,如果 a[11] 没有值就会使得与 key 的比较失败,为了避免这样的情况出现,第9行和第10行的代码就起到这样的作用。总的来说三种有序表的查找本质上是分隔点的选择不同,各有优劣,实际开发是应根据数据的特点综合考虑再进行选择。

2025-12-22 22:03:19 1205

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

拓扑排序其实就是为了解决一个工程是否能够顺利解决的问题,但是我们在解决问题的时候往往需要考虑最短路径的问题,而最短路径在工程中往往不是费时最短时间所完成的路径,反而是最长时间的路线才是所需要的最短时间。由于仍旧是在一个工程中所以我们求活动和事件的时间仍旧需要通过拓扑排序确定,简单的说,我们进行关键路径的步骤就是先正常的进行一遍拓扑排序找到每个顶点(事件)的最早开始的时间。所以在求最早的时间时选择相加更大的时间更新,在求最晚的时间时选选择更短的时间更新。,最后由每个事件的最早最晚时间得出活动的最早最晚时间。

2025-12-18 22:59:21 1505

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

拓扑排序简单地说就是在有向无环图中进行构造序列的过程,基本思路就是先选取入度为0的顶点,然后删除该顶点及该顶点的所有出度的弧,重复直到将全部顶点输出或者图中不存在入度为0的顶点。由于拓扑排序的过程中需要删除顶点所以用邻接表会更方便,同时考虑到对顶点的入度有判断,所以在顶点表结点中加入新的入度域。在主体代码中我们还需要栈来辅助,以便避免每次查找时都需要去遍历顶点表来找又没有入度为0的点,主体代码如下。函数即有删除入读为0的顶点的尾弧功能,又有入栈新的入度为0的结点的功能。在邻接表中所相连的后续结点,也就是。

2025-12-17 22:05:36 302

原创 最短路径---Floyd算法

算法的代码实现还是比较简单的,先初始化两个矩阵后,就再通过判断改变矩阵中的值,这个二维数组的表达形式可以看成从一个顶点到另一个顶点。也就是说,矩阵的角标其实就是通过第几个点来寻找是否通过该点可以寻找到更短的路径的标识。总体来说还是很简单的代码形式,只不过时间复杂度比较大,这点也是美中不足的地方。简单图我们很容易就明白,但是不能反应什么问题,所以我们依旧通过我们的复杂网图来讲解接下来的代码。算法的原理是类似的只不过表达的形式不同。的-1次矩阵存放的是直接到达的权值,而右边。如下的一个简单的图中,

2025-12-14 21:56:03 542

原创 最短路径---Dijkstra算法

前几行的代码依旧是将数据进行初始化(不过在第一个for循环时对D数组的处理其实和Prim算法其中对存储权值的数组的操作方式是一样的),直到主循环时这时的V从1开始因为V0是起始点。然后再循环修改一整个之前的路径直到确保现在的路径是最短的,D数组的带权值是V0到目标顶点的前一个顶点的最小的权值总和。下面通过例子说明,如下图是一个有向图。Dijkstra是一个按路径长度递增的次序产生最短路径的算法,意思就是我们寻找V0到V8不是一步就求出了最短路径,而是一步步的求出它们之间顶点的最短路径,最后的出结果。

2025-12-11 17:33:02 229

原创 最小生成树---Kruskal算法

算法则是通过随机找点后判断各顶点的每个边权值的大小。但是我们在找了大量的边权值后可能会遇到成“环”的情况,我们在连接顶点时需注意不是无脑的寻找边权值小的顶点,而是同时考虑树的形状是否正确。我们既然要先寻找最小权值的边,那么我们就要对临界矩阵进行排序,这时我们就需要用到边集数组来表示。函数用来接收返回来的边集数组中的前后连接的顶点的下标,如果遇到成环的情况就不进行下面的指令。可以看到在边集数组中把顶点与顶点间的权值关系也表示出来了,所以就方便了代码的实现。数组中存放的正好是编入树中的顶点的顺序。

2025-12-07 17:18:33 250

原创 最小生成树---Prim算法

第二个for循环就是主要的功能了,从while循环开始,if中的功能就是将lowcost数组中存储的与V0相关的顶点的边的权值寻找到最小的,并赋值给min,同时把下一个顶点的下标赋值给k,所以说此时lowcost中存储的只有邻接矩阵中一行或一列的数据,并且if里面的功能就是为了存储最小的权值。接下来的for循环的功能就是与上一个顶点的其他路线进行对比,然后将第二行或第二列的更小的权值替换第一行或第一列的权值,因为我们用Prim的时候上一个顶点的剩余路径是可能比下一个顶点的所有路径要短的。

2025-12-06 21:38:13 290

原创 数据结构---广度优先遍历

就是层层扩散,随便找一个顶点为基准,往下所有的出度都算作一层,然后该层所有的顶点的所有出度都算做下一层,不过值得说的是定下一层的顶点的顺序时需要按照本层顶点的顺序的出度,既遵从队列的规则(先入先出)所以我们在找其他顶点时不是一列一列的看,而是按着一个顶点的横向链式结构来看。左上图是我们图的原本的形式,右上图则是方便理解的一种形式,所谓层层扩散就像右图的形式从上到下的一层一层。因为核心的算法还是通过递归的形式实现的所以,我们按照上一层的顺序我们先看。也就是下一个顶点,接下来的步骤的含义和邻接矩阵的相同。

2025-12-04 18:03:54 425

原创 数据结构---深度优先遍历

假设选择A点我们下一个的选择就有B或者F我们只选择其中一条路线进行接下来的遍历,我们选择B接下来的操作同上,一直选择直到顺序为ABCDEFGH。此时我们发现整条路已经走到了尽头,H周围没有其他未遍历的顶点但是,我们在查询顶点表中发现仍有未遍历的顶点,所以我们一步步退回寻找未遍历的顶点,我们在找到D顶点时发现可以寻找到最后的顶点 I ,于是我们完成了遍历。由于是无权网图,所以在创建无向网图邻接矩阵的时候,邻接矩阵的初始化为0,并且在处理边数的循环中有边的设为1(符合无权值无向网图邻接矩阵的特性)。

2025-12-03 20:55:21 305

原创 数据结构---图的初理解

邻接矩阵在邻接矩阵的存储方式中,一个一维数组存储图中的顶点,一个二维数组(既邻接矩阵)存储图中边或弧的信息。如图所示的无向图的边数组中,为0的项即不存在从数据本身到它本身的路径,而在邻接矩阵中为1的项即为有边的项,所以在邻接矩阵中可以很容易的知道该图中的信息。还有一点在无向图中比较重要的性质就是在其邻接矩阵中斜对角是对称的即关于Vi、Vj(i=j)的斜线对称。而在有向图中方法是差不多的,在邻接矩阵中寻找有向图的中某一个顶点的入度和出度也会变得容易。而在网图中邻接矩阵中的数值由于受到了边的权值的影响不能仅为单

2025-12-02 17:06:07 870

原创 数据结构---二叉树的初理解

希望有能看到的大佬指出我文章中的不足和错误,因为我现在也只不过是仍在学习中的学生罢了,另外我写作的思路来自于程杰老师的《大话数据结构》一书中,所以我所写文章的一些地方会有相同的地方,不过也是我在自学中所遇到的一些问题和疑惑,我写出来仅仅是为了帮助可能在使用这本书时可能有同样疑惑的人。相信讲完上面的左子树的整体遍历也大致明白了右子树该如何遍历,C视为右子树的根结点,输出C进入左子树输出E,因为E没有左孩子所以进行右子树的遍历输出 I,C的整体左子树遍历完毕进入右子树只剩下了F,输出F遍历完毕。

2025-11-22 18:44:58 945 1

原创 链表,链栈,队列的链式存储的理解

就比如一个房间里面的东西就是实际的数据,而其中的指针就是门牌号,虽然门牌号在房子上面贴着,但是他的实际意义是指示一个房间(只不过在链表中这个门牌指向的是下一个房间)。而入栈操作其实和链表中的尾插法大同小异,就像上面我所说的重要的部分是插入的原理,所以入栈的步骤仍然是,创建新结点、新结点的数据与赋值为elem、新结点的指针域为栈顶指针(这里要说明的是由于栈的性质新结点的next指向的其实是前一个结点所以next才会赋值为栈顶指针)、重新让栈顶指针保持到栈顶的位置、size大小自增。”,“为什么代码要这样写?

2025-11-02 11:58:03 518 1

空空如也

空空如也

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

TA关注的人

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