图和带权图(数据结构13-14章——读书笔记)

2023-10-27

一. 图

在计算机程序设计中,图是最常用的结构之一。一般来说,用图来帮助解决的问题类型与本书中已经讨论过的问题类型有很大差别。如果处理一般的数据存储问题,可能用不到图,但对某些问题,图是必不可少的。

1.1 图简介

图是一种与树有些相像的数据结构。实际上,从数学意义上说,树是图的一种。然而,在计算机程序设计中,图的应用方式与树不同。
图通常有一个固定的形状,这是由物理或抽象的问题所决定的。例如,图中节点表示城市,而边可能表示城市间的班级航线。另一个更抽象的例子是一个代表了几个单独任务的图,这些任务是完成一个项目所必须的。在图中,节点可能代表任务,有向边(在一端带一个箭头)指示某个任务必须在另一个任务前完成。在这种情形下,图的形状取决于真实世界的具体情况。
当讨论图时,节点通常叫做顶点。

1.1.1 定义

图只是显示了顶点和边的关系——即,哪些边连接着哪些顶点。它本身并不涉及物理的远近和方向。

  • 邻接
    如果两个顶点被同一条边连接,就称这两个顶点是邻接的。和某个指定顶点邻接的顶点有时叫做它的邻居。

  • 路径
    路径是边的序列。

  • 连通图
    如果至少有一条路径可以连接起所有的顶点,那么这个图通常被称作连通的,反之就是非连通的。
    非连通图包含几个连通子图。

  • 有向图和带权图
    图中的边没有方向,可以从任意一边到另一边,称作无向图。只能沿着边朝一个方向移动的图称为有向图,允许移动的方向在图中通常用边一端的箭头表示。
    在某些图中,边被赋予一个权值,权值是一个数字,它能代表两个顶点间的物理距离,或者从一个顶点到另一个顶点的时间,或者是两点间的花费。这样的图叫做带权图。

1.1.2 在程序中表示图

  • 顶点
    在大多数情况下,顶点表示某个真实世界的对象,这个对象必须用数据项来描述。因此通常用一个顶点类的对象来表示一个顶点。
    顶点对象能挡在数组中,然后用下标指示。顶点也可以放在链表或其他数据结构中。不论使用什么结构,存储只为了使用方便。这与如何让连接点没有关系。要达到这个目的,还需要其他机制。

  • 图并不像树,拥有几种固定的结构。图的每个顶点可以与任意多个顶点连接。为了模拟这种自由形式的组织结构,一般用两个方法表示图:即邻接矩阵和邻接表。(如果一条边连接两个顶点,这两个顶点就是邻接的。)
  • 邻接矩阵
    邻接矩阵是一个二维数组,数据项表示两点间是否存在边。如果图有N个顶点,邻接矩阵就是N*N的数组。
    顶点被用作行和列的标题。两个顶点间有边则标识为1,没有边则标识为0(也可以使用布尔变量的true/false值来标识)。
    邻接矩阵的上三角是下三角的镜像:两个三角包含了同样的信息。这个冗余信息看似低效,但在大多数计算机语言中,创造一个三角形数组比较困难,所以只好求其次接收这个冗余。这也要求当增加一条边时,必须更新邻接矩阵的两部分,而不是一部分。
  • 邻接表
    表示边的另一种方法是邻接表。邻接表中的表是指链表。实际上,邻接表是一个链表数组(或者是链表的链表)。每个单独的链表表示了有哪些顶点与当前顶点邻接。
    链表中每个节点都是一个顶点。邻接表表示了当前顶点与哪些顶点连接——即两个顶点间存在边,而不是表示顶点间的路径。

1.1.3 在图中添加顶点和边

为了向图中添加顶点,必须用new保留字生成一个新的顶点对象,然后插入到顶点数组vertexList中。在模拟真实世界的程序中,顶点可能包含许多数据项,但是为了简便起见,这里假定顶点只包含单一的字符。因此顶点的创建用下面的代码:
vertexList[nVerts++]=new Vertex(‘F’);
这就插入了顶点F,nVerts变量是图中当前顶点数。
怎样添加边取决于用邻接矩阵还是用邻接表表示图。假定使用邻接矩阵并考虑在顶点1和顶点3之间加一条边。这些数字对应vertexList数组的下标,顶点存储在数组的对应位置。首次创建邻接矩阵adjMat时,初值为0。添加边的代码如下:
adjMat[1][3]=1;
adjMat[3][1]=1;
如果使用邻接表,就把1加到3的链表中,然后把3加到1的链表中。

1.1.4 Graph类

在Graph类中,vertexList数组的下标唯一地表示一个顶点。

1.2 搜索

在图中实现的最基本的操作之一,就是搜索从一个指定顶点可以到达哪些顶点。还有另一种情形可能需要找到所有当前顶点可到达的顶点。
假设已经创建了这么一个图。现在需要一种算法来提供系统的方法,从某个特定顶点开始,沿着边移动到其他顶点。移动完毕后,要保证访问了和起始点相连的每一个顶点。访问意味着在顶点上的某种操作,例如显示操作。
有两种常用的方法可以用来搜索图:即深度优先搜索(DFS)广度优先搜索(BFS)。它们最终都会到达所有连通的顶点。深度优先搜索通过栈来实现,而广度优先搜索通过队列实现。不同的机制导致了搜索的不同方式。

1.2.1 深度优先搜索

在搜索到尽头的时候,深度优先搜索用栈记住下一步的走向。

  • 示例:

在这里插入图片描述
图中的数字显示了顶点被访问的顺序。
为了实现深度优先搜索,找一个起始点——本例为顶点A。需要做三件事:首先访问该顶点,然后把该顶点放入栈中,一遍记住它,最后标记该点,这样就不会再访问他。
接着开始访问与A相连的顶点,假设顶点按字母访问,所以下一步访问顶点B。然后标记它,放入栈中。
现在已经访问了顶点B,相同的事情:找下一个未访问的顶点,也就是F。这个过程称作规则1:

规则1
如果可能,访问一个邻接的问访问顶点,标记它,并把它放入栈中。

再次应用规则1,访问顶点H。因为没有和H邻接的未访问顶点,下面是规则2:
规则2
当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
根据这条规则,从栈中弹出H,这样就又回到了顶点F。F也没有与之邻接且未访问的顶点了。那么再弹出F,依此类推。这时只有顶点A在栈中。
然而A还有未访问的邻接点,所以访问下一个顶点C,因为C是这条线的终点,所以从栈中弹出它,再次回到A点。接着访问D、G、I。当到达I时,弹出返回A顶点,接着访问E顶点,回到A顶点。
最终A也没有未访问的邻接点,所以把它也弹出栈。现在栈中已无顶点。下面是规则3:
规则3
如果不能执行规则1和规则2,就完成了整个搜索过程。
栈的内容就是刚才从起始顶点到各个顶点访问的整个过程。从起始顶点出发访问下一个顶点时,就把这个顶点入栈。回到起始顶点时,出栈。访问顶点的顺序是ABFHCDGIE。
深度优先搜索算法要得到距离起始点最远的顶点,然后在不能继续前进的时候返回。使用深度这个术语表示与起始点的距离,便可以理解“深度优先搜索”的意义。

1.2.2 广度优先搜索

正如深度优先搜索中看到的,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中,算法好像要尽可能地靠近起始点。它首先访问起始顶点地所有邻接点,然后再访问较远地区域。这种搜索不能用栈,而要用队列来实现。

  • 示例:
    在这里插入图片描述A是起始点,开始访问A,并标记为当前顶点。然后应用以下几条规则:
    规则1:
    访问下一个未来访问的邻接点(如果存在),这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
    规则2:
    如果因为已经没有未访问顶点而不能执行规则1,那么从队列头取一个顶点(如果存在),并使其成为当前顶点。
    规则3
    如果因为队列为空而不能执行规则2,则搜索结束。
    如上规则,需要先访问所有与A邻接的顶点,并在访问的同时把它们插入到队列中。现在已经访问了ABCDE,这时队列包含BCDE,已经没有与顶点A邻接的顶点了,所以从队列中取出B,寻找与B邻接的顶点。这时,找到F,把F插入队列中。依此类推,直至发现没有其他的访问点,这时队列为空,所以从过程中退出。
    在每一时刻,队列所包含的顶点是那些本身已经被访问,而邻接点还有未被访问的顶点。(对比深度优先搜索,栈的内容是起始点到当前顶点经过的所有顶点。)顶点访问的顺序为ABCDEFGHI。
    广度优先搜索有一个有趣的属性:它首先找到与起始点相距一条边的所有顶点,然后是与起始点相距2条边的顶点,依此类推。如果要寻找起始顶点到指定顶点的最短距离,那么这个属性非常有用。首先执行BFS,当找到指定顶点时,就可以说这条路径是到这个顶点的最短路径。如果有更短的路径,BFS算法就应该已经找到过它了。

1.3 最小生成树

使用最少的边连接所有顶点,这组成了最小生成树(MST)。
对于给定的一组顶点,可能有很多种最小生成树。最小生成树边E的数量总比顶点V的数量小1:
E=V-1
attention:不必关心边的长度。并不需要找到一条最短的路径,而是要找最少数量的边。
创建最小生成树的算法与搜索的算法几乎是相同的。它同样可以基于广度优先搜索或深度优先搜索。
在执行深度优先搜索过程中,记录走过的边,就可以创建一棵最小生成树。
最小生成树比较容易从深度优先搜索得到,这是因为DFS访问所有顶点,但只访问一次。它绝不会两次访问同一个顶点。当它看到某条边将到达一个以访问的顶点,就不会走这条边。它不遍历那些不可能的边。因此,DFS算法走过整个图的路径必定是最小生成树。

1.4 有向图的拓扑排序

拓扑排序是可以用图模拟的另一种操作。它可用于表示一种情况,即某些项目或事件必须按特定的顺序排列或发生。

1.4.1 有向图

当边有方向时,图叫做有向图。在有向图中,只能沿着边指定的方向移动。
有向图和无向图的区别是有向图的边在邻接矩阵中只有一项。
对于前面讨论的无向图,邻接矩阵的上下三角是对称的,所以一半的信息是冗余的。而有向图的邻接矩阵中所有行列值都包含必要的信息。它的上下三角是不对称的。
A —— >> B
如果用邻接表表示,那么A在它的链表中有B,但不同于无向图的是,B的链表中不包含A。

1.4.2 拓扑排序

将图按照先后关系进行排列,叫做为图进行拓扑排序。当用算法生成一个拓扑序列时,使用的方法和代码的细节决定了产生哪种拓扑序列。
工作进度是一个重要例子。用图对工作进度建模叫做关键路径分析。
拓扑排序算法的思想虽然不寻常但是很简单。有两个步骤是必需的:
步骤1:
找到一个没有后继的顶点。
顶点的后继也是一些顶点,它们是该节点的直接“下游”——即,该节点与它们由一条边相连,并且边的方向指向它们。如果有一条边从A指向B,那么B是A的后继。
步骤2
从图中删除这个顶点,在列表的前面插入顶点的标记。
重复步骤1和步骤2,直到所有顶点都从图中删除。这时,列表显示的顶点顺序就是拓扑排序的结果。
删除顶点似乎是一个极端步骤了,但是它是算法的核心。如果第一个顶点不处理,算法就不能计算出要处理的第二个顶点。如果需要,也可以在其他地方存储图的数据(顶点列表或邻接矩阵),然后在排序完成后恢复它们。
算法能够执行是因为,如果一个顶点没有后继,那么它肯定是拓扑序列中的最后一个。一旦删除它,剩下的顶点中必然有一个没有后继,所以它成为下一个拓扑序列中的最后一个,依此类推。
拓扑排序算法既可以用于连通图,也可以用于非连通图。这可以模拟另外一种有两个互不相关的目标的情况。

1.4.3 环和树

有一种图是拓扑排序算法不能处理的,那就是有环图。什么是环?它是一条路径,路径的起点和终点都是同一个顶点。
不包含环的图叫做树。二叉树和多叉树就是这个意义上的树。然而在图中提出的树比二叉树和多叉树更具有一般意义,因为二叉树和多叉树定死了子节点的最大个数。在图中,树的顶点可以连接任意数量的顶点,只要不存在环即可。
要计算出无向图是否存在环也很简单。如果有N个顶点的图有超过N-1条边,那么它必定存在环。
拓扑排序必须在无环的有向图中进行。这样的图叫做有向无环图,缩写为DAG。

1.5 有向图的连通性

关于连通性的问题是:如果从一个指定的顶点出发,能够到达哪些顶点?

1.5.1 连通性表

有向图的连通性表:依次从每个顶点开始搜索,后面的是能够到达的顶点(直接或者通过其他顶点)。

1.5.2 Warshall算法

在有些应用中,需要快速地找出是否一个顶点可以从其他顶点到达。
可以检索连通性表,但是那要查看指定行地所有表项,需要O(N)地时间(N是指定顶点可到达的顶点数目平均值)。
可以构造一个表,这个表将立即(即,O(1)的复杂度)告知一个顶点对另一个点是否是可达的。这样的表可以通过系统地修改图的邻接矩阵得到。这种修正过的邻接矩阵表示的图,叫做原图的传递闭包。
attention:在原来的邻接矩阵中,行号代表从哪里开始,列号代表边到哪里结束。(在连通表中排列是类似的。)行C列D的交叉点为1,表示从顶点C到顶点D有一条边。可以一步从一个顶点到另一个顶点。
可以用Warshall算法把邻接矩阵变成图的传递闭包。算法用有限的几行做了很多工作。它基于一个简单的思想:
如果能从顶点L到M,并且能从顶点M到N,那么可以从L到N。
这里已经从两个一步路径,到一个两步路径。邻接矩阵显示了所有的一步路径,所以它可以很好的应用这个规则。

1.5.3 Warshall算法的实现

实现Warshall算法的一个方法是用三层嵌套的循环。外层循环考察每一行:称它为y变量。它里面的一层循环考察行中的每个单元,它使用变量x。如果在单元(x,y)发现1,那么表明有一条边从y到x,这时执行最里层循环,它使用变量z。
第三个循环检查列y的每个单元,看是否有边以y为终点。(attention:y在第一个循环中作为行,在这个循环中作为列。)如果行z列y的值为1,说明有一条边从z到y。一条边从z到y,另一条从y到x,就可以说有一条路径从z到x,所以把(z,x)置为1。

二. 带权图

带权图中,边带有一个数字,它叫做权,它可能代表距离、耗费、时间或其他意义。

2.1 带权图的最小生成树

计算机算法(除非它可能是神经网络)不能一次“知道”给定问题的所有数据;它不能处理全面的大图,只能一点一点地得到数据,随着处理过程地深入,不断修改问题地结果。对于图来说,算法从某个顶点开始工作,首先得到这个点附近的数据,然后找到更远顶点的数据。

2.1.1 设计算法

  • 优先级队列
    执行算法的关键行为是用优先级队列来实现用于反复选择最小造价值的表,而不用链表或数组。这是解决最小生成树的有效方式。在正式的程序中,优先级队列可能基于堆来实现。这会加快在较大的优先级队列中的操作。然而在实例程序中,将用数组实现优先级队列。
  • 算法要点
    从一个顶点开始,把它放入树的集合中。然后重复做下面的事情:
    1.找到从最新的顶点到其他顶点的所有边,这些顶点不能再树的集合中。把这些边放入优先级队列。
    2.找出权值最小的边,把它和它所到达的顶点放入树的集合中。

重复这些步骤,知道所有顶点都在树的集合中。这时,工作完成。
在步骤1中,“最新的”意味着最近放入树中的。此步骤的边可以在邻接矩阵中找到。步骤1完成后,表中包含了所有的边,这些边都是从树中顶点到它们的不在树中的邻接点(边缘点)的连接。

  • 无用边
    在程序算法中,要确保优先级队列中不能有连接已在树中的顶点的边。每次向树中增加顶点后,都要遍历优先级队列查找并删除这样的边。这样做了以后,要使优先级队列中在任意时刻只保持一条从树中顶点到某边缘顶点的边就变得容易了。也就是说,优先级队列中应该只包含一条到达某个第二类顶点的边。
  • 在优先级队列中寻找目的地重复的边
    如何保证以每个第二类顶点为目的地的边只有一条?每次向树中增加边的时候,一定要确保没有其他边也达到同样的顶点。如果有,只保留最小权值的边。
    这使得在优先级队列中逐项查找成为必要的一步操作。查找的目的是看是否有这样的重复边。优先级队列设计初衷本不为随机访问的,所以这不是一个有效的方法。然而,在这种情况下,必须违反一下优先级队列的设计思想。

2.2 最短路径问题(SPP)

可能在带权图中最常遇到的问题就是,寻找两点之间的最短路径问题。
这里所说的最短并不总是指距离上的最短;它也可以代表最便宜,最快或最好的路径,或其他衡量标准。

2.2.1 Dijkstra算法

为解决最短路径问题而提出的方法叫做Dijkstra算法,这个算法的实现基于图的邻接矩阵表示法。它不仅能够找到任意两点间的最短路径,还可以找到某个指定点到其他所有顶点的最短路径。
最短路径算法的关键数据结构是一个数组,它保持了从源点到其他顶点(终点)的最短路径。在算法执行过程中这个距离是变化的,直到最后,它存储了从源点开始的真正最短距离。
不仅应该记录从源点到每个终点的最短路径,还应该记录走过的路径,但不必要明确记录整个路径,只需要记录终点的父节点(即到达终点前到达的顶点)。

2.3 每一对顶点之间的最短路径问题

在带权图中,用一张表给出任意两个顶点间的最低耗费,这对顶点可能通过几条边相连。这种问题叫做每一对顶点之间的最短路径问题。
Warshall算法可以很快的创建这样的表,来显示从某个顶点通过一步或若干步到达其他顶点。带权图中类似的方法叫做Floyd算法。Floyd算法的实现与Warshall算法类似。然而,在Warshall算法中当找到一个两段路径时,只是简单的在表中插入1,在Floyd算法中,需要把两端的权值相加,并插入它们的和。

2.4 效率

图的表示方法有2种,邻接矩阵和邻接表。
如果使用邻接矩阵,前面讨论的算法大多需要O(V2)的时间级,这里V是顶点的数量。因为它们几乎都检查了一遍所有的顶点,具体方法是在邻接矩阵中扫描每一行,依次查看每一条边。换句话讲,邻接矩阵的每个单元,一共有V2个单元,都被扫描过。
对于规模大的矩阵,O(V2)的时间级不是非常好的性能。如果图是密集的,那就没什么提高性能的余地。
然而许多图是稀疏的,与稠密相反。其实并没有一个确定数量的定义说明多少条边的图是稠密或稀疏的,但是如果在一个大图中每个顶点只有很少几条边相连,那么这个图通常被认为是稀疏的。
在稀疏图中,使用邻接表的表示方法代替邻接矩阵,可以改善运行时间。(因为不必浪费时间来检索邻接矩阵中没有边的单元。)
对于无权图,邻接表的深度优先搜索需要O(V+E)的时间级,这里V是顶点的数量,E是边的数量。对于带权图,最小生成树算法和最短路径算法都需要O((E+V)logV)的时间级,在大型的稀疏图中,与邻接矩阵方法的时间级相比,这样的时间级可使性能大幅提升。当然,算法会更加复杂一些。
Warshall算法和Floyd算法执行需要O(V3)的时间级。这是因为在它们的实现中使用了三层嵌套的循环。

来源:《数据结构》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图和带权图(数据结构13-14章——读书笔记) 的相关文章

  • Windows下通过远程桌面连接向远程电脑传输文件

    一 打开远程桌面连接 在搜索框中输入 远程桌面连接 进入下面的界面 二 配置连接 点击显示选项 选择本地资源 查看详细信息 选择要使用的磁盘 我要使用D盘中的文件 所以勾选了D盘 确定后点击连接 三 传输文件 连接到远程服务器 打开文件管理
  • 在STM32上运行ROS节点——rosserial&stm32开发及调试方法

    近期接手了一些ROS机器人项目 这里将开发中遇到的问题和解决方法记录下来 stm32强大的外设资源为机器人底层设备控制带来了极大的便利 本文简述借助rosserial项目在stm32中运行ROS节点的方法 基本原理 ref http wik
  • 什么是数据湖 Data Lake

    什么是数据湖 Data Lake 背景 随着近几年机器学习的兴起对数据的需求更加灵活 如果从数据仓库中提数会有一些问题 比如 数据都是结构化的 做算法的经常要理解数仓模型 甚至要深入到做了什么业务处理 很多处理都不是他们想要的 数据是经过处

随机推荐

  • 转置矩阵(matrix transpose)和逆矩阵(matrix inverse)的相关公式

    转载自 https blog csdn net yinhun2012 article details 84236202 这一篇是为了后面着色效果的数学基础做积累 之前我们使用矩阵的大部分情况都是直接的仿射空间变换 就是仿射空间A变换到仿射空
  • Android:ARouter原理源码解析

    文章目录 前言 一 ARouter使用 二 ARouter初始化 init 函数 整体 LogisticsCenter初始化 拦截器初始化 三 跳转解析 跳转 总结 前言 一 ARouter使用 ARouter的基本使用请参考这篇博客 AR
  • 分治03--二叉搜索树和双向链表

    分治03 二叉搜索树和双向链表 jz26 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 输入一棵二叉搜索树 将该二叉搜索树转换成一个排序的双向链表 要求不能创建任何新的结点 只能调整树中结点指针的指向 测试用例 输入 10
  • Thinkcmf 后台弹框页面代码

    thinkcmf是基于layer做的弹出层 https www layui com doc modules layer html 可以看layer的文档学习 选择信息 列表展示 html页面
  • Failed to remove the service because the service is running Stop the service and try again解决方法

    解决方法 Failed to remove the service because the service is running Stop the service and try again mysqld remove 报错 在Window
  • 微信回调 java_详解APP微信支付(java后台_统一下单和回调)

    1 微信配置信息 global properties 2 方法wxpay用于生成预支付订单信息 方法notifyWeiXinPay用于微信支付成功后的回调 注意 在手机端使用微信支付成功后 微信服务器会根据提供的回调地址进行回调 param
  • JavaWeb笔记:第07章 MVC

    JavaWeb笔记 第07章 MVC EL JST Filter Listener JQuery AJAX Maven JSON Redis Linux Nginx 1 MVC 开发模式 2 EL表达式 2 1 概念 作用 语法 2 2 E
  • Springboot初识--Bean的理解

    注解下的Spring Ioc Spring所提供的两个核心理念 一个是控制反转 Inversion of Control IoC 另一个是面向切面编程 Aspect Oriented Progarmming AOP IoC容器是spring
  • Mybatis中parameterType的用法

    在mybatis映射接口的配置中 有select insert update delete等元素都提到了parameterType的用法 parameterType为输入参数 在配置的时候 配置相应的输入参数类型即可 parameterTy
  • rsync安装及使用详细步骤

    目录 1 介绍rsync 2 rsync的安装以及操作方法 3 启动rsync 4 文件传输 5 效验 6 总结 rsync 是一个开源的命令行工具 用于在不同的主机之间同步文件和目录 它可以通过远程 shell 或 rsync 协议 默认
  • SQL语句学习系列(1)

    目录 查询语句 1 查询所有列的所有行 2 查询指定列的所有行 3 查询满足条件的行 4 查询满足多个条件的行 6 查询满足条件的行数 7 查询满足条件的唯一值 8 查询满足条件的分组统计 9 查询满足条件的平均值 10 查询满足条件的最大
  • C语言练习题(14) 有以下函数,该函数的功能是( )int fun(char *s) { char *t = s; while(*t++); return(t-s); }(非常详细的讲解)

    1 有以下函数 该函数的功能是 int fun char s char t s while t return t s A 比较两个字符的大小 B 计算s所指字符串占用内存字节的个数 C 计算s所指字符串的长度 D 将s所指字符串复制到字符串
  • 深入研究源码:Android10.0系统启动流程(三):Zygote

    前言 研究过程中参考了很多的文章 这篇源码分析 可能是全网最全的Zygote源码分析了 如果觉得这篇源码分析太干 也可以先看一下后续的相关总结 戳https juejin im post 6844903966665539591 全文概览 我
  • java项目的心得,java项目的代码层次的架构划分

    java项目使用的架构是ssm Spring SpringMVC MyBatis 一 后台代码一般分三层 Controller Service Dao 1 Controller层是对前端或者接口的响应一个逻辑处理的层 这个层级一般调用的是S
  • 3、MyBatisPlus的CRUD 接口

    MyBatisPlus的CRUD 接口 一 insert 1 插入操作 2 主键策略 二 update 1 根据Id更新操作 2 自动填充 3 乐观锁 三 select 1 根据id查询记录 2 通过多个id批量查询 3 简单的条件查询 4
  • Nor flash 页写地址与数据大小的限制

    厂商提供的flash手册如下 如果页写指令的地址不是256的整数倍 并且写入的数据量超过了当前地址所在页的边界 则超过的那些数据会重新写入当前页的首地址 即256的整数倍地址 所以 在进行页写的时候 要注意这个限制 跨页写数据时注意分多个页
  • JAVA验证数字的整数位长度及小数据位长度

    文章目录 一 案例说明 二 使用步骤 1 引入库 2 读入数据 一 案例说明 验证数字的整数位长度及小数据位长度 二 使用步骤 1 引入库 代码如下 示例 import java util regex Matcher import java
  • 9、无须光照的模型假阴影实现 URP

    模型阴影 我们在实际项目中 经常会有模型影子的需求 这个时候如果使用光照的话 在移动端性能消耗太大 如果使用一个假的阴影片 效果又不太好 我们希望有能够有和灯光系统一样的阴影效果 我们通过模拟灯光的方式来实现 之前我们写的shader都是对
  • USB设备开发---- usb描述符概述

    说到USB设备 不得不提到各种描述符 descriptors 一般来说 描述符有如下几种 1 设备描述符 Device Descriptors 2 配置描述符 Configuration Descriptors 2 接口描述符 Interf
  • 图和带权图(数据结构13-14章——读书笔记)

    一 图 在计算机程序设计中 图是最常用的结构之一 一般来说 用图来帮助解决的问题类型与本书中已经讨论过的问题类型有很大差别 如果处理一般的数据存储问题 可能用不到图 但对某些问题 图是必不可少的 1 1 图简介 图是一种与树有些相像的数据结