6.5.图的基本操作
一.图的基本操作:
1.判断图G是否存在弧<x,y>或边(x,y):
a.使用邻接矩阵来实现判断无向图G中是否存在边(x,y):
以上述图片的无向图为例,用邻接矩阵存储无向图时想要判断两个顶点之间是否有边是很方便的,
比如判断顶点B和D之间是否有边,只需要判断邻接矩阵中B行D列(D行B列也可以,因为无向图的边没有方向)的值是否为1即可,为1代表顶点B和D之间有直达的边,为0代表顶点B和D之间不存在直达的边,
因此使用邻接矩阵来实现判断无向图G中是否存在边(x,y)的时间复杂度为O(1)。
b.使用邻接表来实现判断无向图G中是否存在边(x,y):
以上述图片的无向图为例,
比如判断顶点B和D之间是否有边,在邻接表中顶点B在1索引上,顶点D在3索引上,由于顶点B对应的链表中没有索引3,所以顶点B和D之间没有直达的边(也可以判断顶点D对应的链表,原理相同),
对于时间复杂度,最好的时间复杂度就是在顶点对应的链表中第一个结点上就是要查找的顶点的索引,此时时间复杂度为O(1);假设有V个顶点,那么其中一个顶点最多关联|V|-1条边,最坏的时间复杂度为该顶点关联|V|-1条边(意味着该顶点对应的链表包含了除该顶点以外的所有顶点)且遍历完该顶点对应的整个链表后在最后一个结点上才找到了要查找的顶点的索引或者没有找到要查找的顶点的索引(此时意味着要查找的顶点不在图中),因此时间复杂度最坏为O(|V|-1),等价于O(|V|),
因此使用邻接表来实现判断无向图G中是否存在边(x,y)的时间复杂度为O(1)到O(|V|)。
显然在判断无向图G是否存在边(x,y)的操作中使用邻接矩阵比邻接表更高效一些。
c.使用邻接矩阵来实现判断有向图G中是否存在弧<x,y>:
以上述图片的有向图为例,
比如判断顶点A和B之间是否有弧,需要判断邻接矩阵中A行B列和B行A列,因为有向图的弧存在方向,顶点A到顶点B可能没有弧,但顶点B到顶点A可能就存在弧,A行B列的值为1,说明顶点A有指向顶点B的弧,B行A列的值为0,说明顶点B没有指向顶点A的弧,综上,顶点A和B之间有弧,
因此使用邻接矩阵来实现判断有向图G中是否存在弧<x,y>的时间复杂度为O(1)。
d.使用邻接表来实现判断有向图G中是否存在弧<x,y>:
以上述图片的有向图为例,
比如判断顶点A和B之间是否有弧,在邻接表中顶点A在0索引上,顶点B在1索引上,由于顶点B对应的链表中没有索引0,所以顶点B没有指向顶点A的弧,由于顶点A对应的链表中有索引1,所以顶点A有指向顶点B的弧,综上,顶点A和B之间有弧,
对于时间复杂度,最好的时间复杂度就是在顶点对应的链表中第一个结点上就是要查找的顶点的索引,此时时间复杂度为O(1);假设有V个顶点,那么其中一个顶点最多关联2(|V|-1)条弧(因为弧包括入弧和出弧),最坏的时间复杂度为该顶点关联2(|V|-1)条弧(意味着该顶点对应的链表包含了除该顶点以外的所有顶点)且遍历完该顶点对应的整个链表后在最后一个结点上才找到了要查找的顶点的索引或者没有找到要查找的顶点的索引(此时意味着要查找的顶点不在图中),因此时间复杂度最坏为O( 2(|V|-1) ),等价于O(2|V|-2),等价于O(|V|),
因此使用邻接表来实现判断有向图G中是否存在弧<x,y>的时间复杂度为O(1)到O(|V|)。
显然在判断有向图G是否存在弧<x,y>的操作中使用邻接矩阵比邻接表更高效一些。
2.列出图G中与结点x邻接的边:
a.无向图中使用邻接矩阵找和某一个顶点相连的所有的边:
以上述图片的无向图为例,
要列出图G中与某个顶点邻接的所有的边,只需要遍历某个顶点在邻接矩阵中的某一行或某一列即可(因为无向图的边不存在方向,所以行和列对称),判断哪个地方的元素是1,把元素是1的全部列举出来即可,比如找和顶点B邻接的所有的边,在B行中,只有B行A列、B行E列、B行F列的值为1,所以顶点B与顶点B、A之间的边,顶点B、E之间的边,顶点B、F之间的边邻接,
对于时间复杂度,如果此时有V个顶点,那么时间复杂度就是O( |V| ),因为总共要遍历V个元素。
b.无向图中使用邻接表找和某一个顶点相连的所有的边:
以上述图片的无向图为例,
要列出图G中与某个顶点邻接的所有的边,只需要遍历某个顶点在顺序表中对应的链表即可,
对于时间复杂度,最好的情况是当前的顶点只邻接一条边或者没有邻接任何边,此时的时间复杂度为O(1),最坏的情况就是如果当前图中有V个顶点,某个顶点邻接了除该顶点外每一个顶点上的边,最多会邻接|V|-1条边,此时遍历完链表需要O( |V|-1 )的时间复杂度,等价于O( |V| )。
显然在列出无向图G中与结点x邻接的边的操作中使用邻接表比邻接矩阵更高效一些。
c.有向图中使用邻接矩阵找和某一个顶点相连的所有的边:
以上述图片的有向图为例,
假设此时图中共有V个顶点,要想找到某个顶点的出边,只需要遍历该顶点在邻接矩阵中对应的那一行即可,需要遍历|V|个顶点;要想找到某个顶点的入边,只需要遍历该顶点在邻接矩阵中对应的那一列即可,需要遍历|V|个顶点,找入边和出边的这两个遍历是遍历完其中一个再遍历另一个,所以
综上,有向图中使用邻接矩阵找和某一个顶点相连的所有的边的时间复杂度为O( |V| )。
d.有向图中使用邻接表找和某一个顶点相连的所有的边:
以上述图片的有向图为例,
要列出图中与某个顶点邻接的所有的弧,只需要遍历该顶点所在邻接表中所有的链表即可,
要找某个顶点的出边,只需要遍历邻接表中该顶点对应的链表即可->假设此时图中共有V个顶点,最好的时间复杂度就是当前顶点没有出边即不需要遍历链表,此时时间复杂度为O(1),如果当前顶点指向除了当前顶点外的所有顶点,就意味着要遍历|V|-1个顶点,此时达到最坏时间复杂度为O( |V|-1 ),等价于O( |V| ),所以找出边的时间复杂度是O(1)到O( |V| );
要找指向某个顶点的弧即该顶点的入边,就需要遍历邻接表中所有的链表,因为只有把这些链表都遍历完,才能找全入边,假设图中有E条弧,遍历完所有链表就意味着要判断图中所有的弧,那么找入边的时间复杂度为O( |E| ),
{邻接表中顶点A在0索引上,顶点B在1索引上,顶点A对应的链表中只有1索引,说明顶点A只有指向顶点B的1条弧;顶点E在4索引上,顶点B在1索引上,顶点C在2索引上,顶点E对应的链表中有1索引和2索引,说明顶点E有指向顶点B的弧和指向顶点C的弧,其他同理}
显然在列出有向图G中与结点x邻接的弧的操作中使用邻接矩阵比邻接表更高效一些,但这个不绝对,如果当前的图是稀疏图,意味着弧很少,此时O( |E| )的数量级就很小,此时邻接表的效果也很好。
3.在图G中插入顶点x:
要插入的顶点x刚开始时和图G中的任何顶点都不相连,所以插入操作很方便。
a.使用邻接矩阵来实现在无向图G中插入顶点x:
在上述图片中的无向图中插入顶点x,只需要在存储顶点的顺序表中添加顶点x的数据即可,在邻接矩阵中新添加的顶点x的这一行和这一列一开始都为0,表示顶点x起初不和任何顶点相连:
上述图片的邻接矩阵中看起来要插入许多个0,实际上化0的操作在邻接矩阵初始化时就已经处理过了,所以使用邻接矩阵在无向图中插入顶点x的时间开销只有在存储顶点的顺序表中添加顶点x的数据,因此时间复杂度为O(1)。
b.使用邻接表来实现在无向图G中插入顶点x:
如上述图片所示,只需要在存储顶点的顺序表中插入新顶点x的数据即可,由于新顶点x起初不和任何顶点相连,所以x顶点对应的链表的内容为NULL,因此时间复杂度为O(1)。
c.d.有向图类似,时间复杂度都是O(1)。
4.从图G中删除顶点x:
a.用邻接矩阵表示在无向图G中删除顶点x:
上述图片中,如果删除C顶点,只需要把邻接矩阵中第C行和第C列的数据全部清空即可,清空这些数据以后,比较容易想到的一个方法就是,我们可以让顺序表中C顶点后面的数据依次前移,对于邻接矩阵而言,就需要把断开的部分拼接起来,这么操作的话就意味着会有大量的数据元素需要移动,显然移动这么多的元素开销会很大,所以该方案不科学:
->如果删除C顶点,意味着C顶点不和任意一个顶点相连,对于邻接矩阵而言,只需要把C行和C列的数据都改为0即可(0代表此时的两个顶点互不相连),在顶点的结构体中可以增加一个布尔类型的变量,用于表示某个顶点是否是一个不和任何顶点相连的顶点即可,用该方式实现删除顶点显然要比移动大量元素好很多。由于每删除一个顶点需要修改邻接矩阵中一行和一列的数据,还需要修改表示顶点是否连接顶点的布尔型变量,所以时间复杂度为O( |V| )+O(1),等价于O( |V| ),V为图的顶点个数。
b.用邻接表表示在无向图G中删除顶点x:
上述图片中,如果删除C顶点,顺序表中要删除C顶点的数据以及C顶点对应的链表,其他和C顶点相连的顶点中,对应的链表中需要把关于C顶点的信息删除,如下图:(C顶点在顺序表中的索引为2,所以顺序表中2索引对应的数据删除,再把顺序表中所有链表中关于2的都删除)
邻接表的删除操作中,对于时间复杂度:
最好的情况是当前要删除的C顶点没有连接任何的顶点,这种情况只需要把顺序表里2索引上的C顶点删除即可,时间复杂度为O(1),
最坏的情况就是当前要删除C顶点和除C顶点以外的所有顶点都相连,所以当删除掉顺序表中2索引上的C顶点和对应的链表后,还需要依次遍历其他和C顶点相连的顶点以及对应的链表,链表中最坏的情况是要删除的2索引上的C顶点是在每一条链表的最后一个位置,那么就意味着要遍历所有链表而且要把所有链表都遍历完才能把和C顶点有关的内容删除完,所以最坏的时间复杂度为O( |E| ),E为图G的边,因为要把每一条边都遍历一遍,
所以时间复杂度是O(1)到O( |E| ):
c.用邻接矩阵表示在有向图G中删除顶点x:
思路和用邻接矩阵表示在无向图G中删除顶点x类似。
d.用邻接表表示在无向图G中删除顶点x:
以上述图片为例,删除有向图G中的C顶点,C顶点在顺序表中的2索引上,
如果要删除C顶点的出边,只需要把顺序表中2索引上的C顶点对应的链表中的数据全部删除即可,因为链表里记录的是C顶点指向哪些顶点,最好的情况是C顶点没有出边,无需删除,此时时间复杂度为O(1),最坏的情况是C顶点指向除了C顶点以外的所有顶点,假设此时图G中有V个顶点,那么时间复杂度为O( |V-1| ),等价于O( |V| ),所以删除出边的时间复杂度是O(1)到O( |V| ),
如果要删除C顶点的入边即指向C顶点的边,此时就只能遍历整个邻接表,把除了C顶点对应的链表以外的所有链表中关于2的数据删除,因为C顶点在顺序表中的2索引上,意味着要遍历所有的边,假设图G中有E条边,那么时间复杂度就是O( |E| )。如果是稀疏图的话,边比较少,O( |E| )也不会很大。
5.向图G中添加边:
a.使用邻接矩阵实现在无向图G中添加边:
以上述图片为例,此时要添加无向边(A,E)即添加A和E之间的边,此时只需要把邻接矩阵中A行E列和E行A列的值全部赋值为1即可,时间复杂度为O(1)。
b.使用邻接表实现在无向图G中添加边:
以上述图片为例,此时要添加无向边(C,F)即添加C和F之间的边,由于顺序表中C顶点在2索引上,F顶点在5索引上,所以只需要在顺序表中C顶点对应的链表中末尾添加数据5和F顶点对应的链表中末尾添加数据2即可:
这里采用了链表的尾插法,其实更高效的方法是采用链表的头插法,就是把新的边的信息添加到链表的头部,此时直接在链表头部插入数据即可,所以时间复杂度为O(1),如下:
最坏的情况就是在顶点对应的链表中添加数据时指定了要添加的位置,此时需要遍历链表(详情见"单链表的插入和删除"),假设V为图G中顶点的个数,所以时间复杂度为O( |V| )
->所以使用邻接表实现在无向图G中添加边的时间复杂度为O(1)到O( |V| ),V为图G中顶点的个数:
c.有向图类似。
6.求图G中顶点x的第一个邻接点,若有则返回该邻接点在顺序表中的索引;若顶点x没有邻接点或图G中不存在顶点x,则返回-1:
a.使用邻接矩阵实现求无向图G中顶点x的第一个邻接点,若有则返回该邻接点在顺序表中的索引;若顶点x没有邻接点或无向图G中不存在顶点x,则返回-1:
以上述图片为例,例如要找C顶点的第一个邻接点,可以扫描C行的数据(也可以扫描C列的数据,因为此时是无向图,邻接矩阵是对称的),直到找到第一个1,就找到了第一个和C顶点邻接的点,此时第一个1对应的顶点是A顶点,所以顶点C的第一个邻接点是A顶点。最好的情况就是扫描的第一个顶点就是当前顶点的邻接点,此时的时间复杂度为O(1),最坏的情况就是扫描完一整行(意味着把所有顶点都扫描了)都没有和当前顶点相邻接的点,假设图G中有V个顶点,此时时间复杂度为O( |V| ),所以时间复杂度是O(1)到O( |V| )。
b.使用邻接表实现求无向图G中顶点x的第一个邻接点,若有则返回该邻接点在顺序表中的索引;若顶点x没有邻接点或无向图G中不存在顶点x,则返回-1:
以上述图片为例,例如要找C顶点的第一个邻接点,C顶点在顺序表的2索引上,只需要知道C顶点对应的链表的第一个结点中的数据是多少,此时是0,意味着C顶点的第一个邻接点为顺序表中0索引上的顶点即A顶点,易知时间复杂度为O(1)。如果C顶点没有对应的链表,说明C顶点不和任何顶点邻接。
c.使用邻接矩阵实现求有向图G中顶点x的第一个邻接点,若有则返回该邻接点在顺序表中的索引;若顶点x没有邻接点或有向图G中不存在顶点x,则返回-1:
以上述图片为例,例如C顶点,
找C顶点的出边中C顶点的第一个邻接点需要扫描第C行,直到找到第一个1,就找到了顶点C的出边中第一个和C顶点邻接的点,此时第一个1对应的顶点是A顶点,所以顶点C的出边中第一个邻接点是A顶点,
找C顶点的入边中C顶点的第一个邻接点需要扫描第C列,直到找到第一个1,就找到了顶点C的入边中第一个和C顶点邻接的点,此时第一个1对应的顶点是E顶点,所以顶点C的入边中第一个邻接点是E顶点。
无论是在出边中找还是在入边中找,最好的情况都是扫描的第一个顶点就是当前顶点的邻接点,此时的时间复杂度为O(1),最坏的情况就是扫描完一整行或列(意味着把所有顶点都扫描了)都没有和当前顶点相邻接的点,假设图G中有V个顶点,此时时间复杂度为O( |V| ),所以时间复杂度是O(1)到O( |V| )。
d.使用邻接表实现求有向图G中顶点x的第一个邻接点,若有则返回该邻接点在顺序表中的索引;若顶点x没有邻接点或有向图G中不存在顶点x,则返回-1:
以上述图片为例,例如C顶点,
找C顶点的出边中C顶点的第一个邻接点只需要知道C顶点对应的链表的第一个结点中的数据是多少,此时是0,意味着C顶点的出边中C顶点的第一个邻接点为顺序表中0索引上的顶点即A顶点,易知时间复杂度为O(1)。如果C顶点没有对应的链表,说明C顶点的出边中C顶点不和任何顶点邻接。
找C顶点的入边中C顶点的第一个邻接点需要遍历顺序表中除了C顶点对应的链表以外的所有链表,链表中第一个出现2的链表对应的顶点就是C顶点的入边中C顶点的第一个邻接点,此时链表中第一个出现2的链表对应的顶点是E顶点,所以C顶点的入边中C顶点的第一个邻接点是E顶点->对于时间复杂度,最好的情况是遍历顺序表中第一条链表的第一个元素时就找到了对应的邻接点,此时的时间复杂度为O(1),最坏的情况是遍历完顺序表中所有的链表都没有对应的邻接点,假设图G中有E条边,那么时间复杂度就是O( |E| )。所以时间复杂度就是O(1)到O( |E| )。
更常用的是找某个顶点的出边中该顶点的第一个邻接点。
7.假设图G中顶点y是顶点x的一个邻接点,返回除顶点y之外顶点x的下一个邻接点的顶点号,若顶点y是顶点x的最后一个邻接点,则返回-1:
a.使用邻接矩阵实现假设图G中顶点y是顶点x的一个邻接点,返回除顶点y之外顶点x的下一个邻接点的顶点号,若顶点y是顶点x的最后一个邻接点即顶点y之后顶点x没有邻接点,则返回-1:
以上述图片为例,例如要找C顶点除当前邻接点的下一个邻接点,可以扫描C行的数据(也可以扫描C列的数据,因为此时是无向图,邻接矩阵是对称的),直到找到除当前邻接点的下一个1,就找到了C顶点除当前邻接点的下一个邻接点,假设C顶点当前的邻接点为A顶点,邻接矩阵中A顶点之后的下一个为1的数据对应的顶点是E顶点,所以顶点C除当前邻接点A的下一个邻接点是E顶点。最好的情况就是扫描一次就是除当前邻接点的下一个邻接点,此时的时间复杂度为O(1),最坏的情况就是扫描完一整行(意味着把所有顶点都扫描了)都没有除当前邻接点的下一个邻接点,假设图G中有V个顶点,此时时间复杂度为O( |V| ),所以时间复杂度是O(1)到O( |V| )。
b.使用邻接表实现假设图G中顶点y是顶点x的一个邻接点,返回除顶点y之外顶点x的下一个邻接点的顶点号,若顶点y是顶点x的最后一个邻接点即顶点y之后顶点x没有邻接点,则返回-1:
以上述图片为例,例如要找C顶点除当前邻接点的下一个邻接点,只需要操作C顶点在顺序表中对应的链表即可,假设C顶点此时邻接点是A顶点,A顶点在顺序表中的索引为0,C顶点的链表中数据0的下一个结点中的数据为4,所以C顶点除当前邻接点A的下一个邻接点是顺序表中4索引上的顶点E,其中不需要遍历,所以时间复杂度为O(1)。
有向图类似。
8.获取图G中边(x,y)或弧<x,y>对应的权值,设置图G中边(x,y)或弧<x,y>对应的权值为v:(权值就是边或弧的含义,如权值可以是距离)
对于实现图G中边(x,y)或弧<x,y>的获取权值和设置权值,主要的时间开销就是来源于找边或弧,因为只有获取到边或弧,才能进行获取权值或设置权值,所以实现获取权值和设置权值的这两个操作是和判断某一条边或弧是否存在这个基本操作的时间开销是一样的。
二.总结:
相关文章:
6.5.图的基本操作
一.图的基本操作: 1.判断图G是否存在弧<x,y>或边(x,y): a.使用邻接矩阵来实现判断无向图G中是否存在边(x,y): 以上述图片的无向图为例,用邻接矩阵存储无向图时想要判断两个顶点之间是否有边是很方便的, 比如判…...
2025全新开源双端系统源码:获取通讯录、相册、短信、定位及已装应用信息
分享一套全新上线的双端信息采集系统源码,支持提取通讯录、相册、短信、定位信息及已安装应用数据。源码完全开源,只做轻微测试需要的自取,简易教程放在压缩包里面了,欢迎有需要的朋友自取参考。 下载地址:下载地址.t…...
es基本概念
Elasticsearch 的架构与基本概念 Elasticsearch(简称 ES)是一个开源的分布式搜索和分析引擎,基于 Apache Lucene 构建。它被广泛用于全文搜索、日志分析、实时数据分析等场景。以下是其架构概述及其基本概念的详细解释。 Elasticsearch 的架…...
算法刷题记录——LeetCode篇(2.5) [第141~150题](持续更新)
更新时间:2025-04-04 算法题解目录汇总:算法刷题记录——题解目录汇总技术博客总目录:计算机技术系列博客——目录页 141. 环形链表 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通…...
【Rust学习】Rust数据类型,函数,条件语句,循环
本文专栏:Rust学习 目录 一,数据类型 1,标量类型 1.1,整型 1.2,整型溢出 1.3,浮点数型 1.4,布尔类型 1.5,字符型 2,复合类型 2.1,Tuple(元组) 2.2&am…...
PgVectore的使用
PgVectore的使用 一、PgVector的安装 参照博客:https://blog.csdn.net/u012953777/article/details/147013691?spm1001.2014.3001.5501 二、PgVector的使用 1、创建表与插入数据 定义向量字段: CREATE TABLE items (id SERIAL PRIMARY …...
智能工厂的数字孪生与信息物理系统架构研究
摘要 本文以工业 4.0 为背景,系统分析数字孪生(Digital Twin)与信息物理系统(CPS)在智能工厂中的协同架构。通过构建 "感知 - 映射 - 决策 - 执行" 的四层技术框架,结合三一重工、海尔等企业案例…...
基于YOLO11实例分割与奥比中光相机的快递包裹抓取点检测
本博客来源于CSDN机器鱼,未同意任何人转载。 更多内容,欢迎点击本专栏,查看更多内容。 0 引言 项目采用六轴机械臂搭配末端真空吸盘,从无序包裹中抓取想要的包裹。AI算法需要提供各包裹的抓取点的3D坐标与3D姿态。由于快递包裹含…...
简单程序语言理论与编译技术·22 实现一个从AST到RISCV的编译器
本文是记录专业课“程序语言理论与编译技术”的部分笔记。 LECTURE 22(实现一个从AST到RISCV的编译器) 一、问题分析 1、完整的编译器(如LLVM)需先完成AST到IR的转换,并进行代码优化,再到汇编࿰…...
无锡无人机驾驶证培训费用
无锡无人机驾驶证培训费用,随着科技的迅速发展,无人机在众多行业中发挥着举足轻重的作用。从影视制作到农业监测,再到物流运输与城市规划,无人机的应用场景不断扩展,因此越来越多的人开始意识到学习无人机驾驶技能的重…...
[ctfshow web入门] web5
前置知识 引用博客:phps的利用 当服务器配置了 .phps 文件类型时,访问 .phps 文件会以语法高亮的形式直接显示 PHP 源代码,而不是执行它。.phps被作为辅助开发者的一种功能,开发者可以通过网站上访问xxx.phps直接获取高亮源代码 …...
第五章:架构安全性_《凤凰架构:构建可靠的大型分布式系统》
第五章 架构安全性 一、认证机制 核心知识点: 认证标准: HTTP Basic认证:Base64编码传输凭证,需配合HTTPS使用OAuth 2.0:授权框架,重点掌握四种授权模式: 授权码模式(最安全&#…...
控件主题效果添加程序设计
以下是针对Qt Designer设计的控件添加阴影效果的完整解决方案,结合可视化设置与动态主题支持: 一、基础阴影效果实现方案 1. 通过QSS实现简易阴影(适用于简单需求) /* 使用多重边框模拟阴影效果 */ QFrame#customWidget {borde…...
用swift playground写个ios应用和大模型或者网站交互
import SwiftUIstruct ContentView: View {State private var textFieldText: String ""State private var outputText: String "输出将会显示在这里"private let tip:String "消息已发送,请等待"State private var history:[Stri…...
Mlivus Cloud SDK v2的革新:从痛点剖析到实战优化
目录 从V1到V2:开发者体验的范式转变 深度解析SDK v2的架构革新 1. 统一接口范式:终结API混乱时代 2. 原生异步支持:高并发场景的性能救星 3. Schema Cache机制:性能优化的隐形冠军 4. 全功能REST API:简化集成的关键 实战指南:从迁移到深度优化 平滑迁移策略 性…...
【图像处理基石】什么是AWB?
1. AWB(自动白平衡)的定义 AWB(Auto White Balance)是一种图像处理技术,通过算法校正不同色温光源下图像的色彩偏差,使白色在任何光照条件下都能准确呈现为白色,从而让图像颜色更接近人眼真实感…...
[蓝桥杯 2017 省 B] k 倍区间
P8649 [蓝桥杯 2017 省 B] k 倍区间 题目描述 给定一个长度为 N N N 的数列, A 1 , A 2 , ⋯ A N A_1,A_2, \cdots A_N A1,A2,⋯AN,如果其中一段连续的子序列 A i , A i 1 , ⋯ A j ( i ≤ j ) A_i,A_{i1}, \cdots A_j(i \le j) Ai,Ai1,⋯…...
基于SSM的高校宿舍水电管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
【LLM系列】1.大模型简介
1. 基础 1.1 如何权衡模型的复杂度和性能? ├── a. 模型架构选择 │ ├── 简化架构 │ │ └── 选择较小的网络层数和宽度,降低复杂度; │ │ 可使用高性能基础模型如 Transformers 作为起点,根据需求缩放模型。 │ └──…...
从概念和设计哲学的角度详细解析工厂模式
从概念和设计哲学的角度详细解析工厂模式。 1. 工厂模式的核心目标 解耦:将对象的创建过程与使用过程分离,使用者无需关心对象如何被创建。 统一入口:通过一个接口或方法控制对象的生成,隐藏底层实现细节。 类比现实中的工厂&am…...
AI小白:机器学习VS深度学习
1 特征工程的范式革命 传统机器学习:手工特征工程的艺术 在传统机器学习中,特征工程是一个关键步骤,它涉及将原始数据转化为能够被机器学习模型高效利用的特征。这通常需要领域专家的经验和知识,以手动设计和提取特征。 例如&a…...
对应列表数据的分割和分组
要基于指定的流派列表分割数据,可以使用 布尔索引 或 groupby 结合筛选。以下是具体方法: 场景假设 数据列 genres 中的值可能是多流派的字符串,例如 "drama,action" 或 ["drama", "action"]。目标࿱…...
信息物理系统(CPS):中国 AI(DEEPSEEK)的未来路径
一、引言 人工智能(AI)的发展正从通用模型向垂直领域渗透,而信息物理系统(CPS)作为连接数字世界与物理世界的桥梁,为 AI 提供了新的发展方向。中国 AI 企业如 DEEPSEEK 通过开源策略和本土化优势ÿ…...
SEO长尾词优化实战技巧
内容概要 长尾关键词作为SEO策略的重要组成部分,能够有效捕捉细分领域的精准流量,降低竞争成本的同时提升转化效率。本文系统梳理了从关键词挖掘到流量转化的全链路优化方法,重点解析工具使用、布局策略及搜索意图匹配三大核心模块。通过结合…...
爬虫自动化工具:DrissionPage
1. DrissionPage初始 官网地址:🛰️ 概述 | DrissionPage官网 在当今互联网高速发展的时代,网页数据的获取和处理变得愈发重要。传统的自动化工具如 Selenium 在某些方面逐渐显露出一些局限性,而 DrissionPage 正是在这样的背景下…...
扩展库Scrapy:Python网络爬虫的利器
目录 一、扩展机制的核心原理 二、六大实用扩展库详解 1. 动态渲染神器:scrapy-playwright 2. 分布式架构:scrapy-redis 3. 反反爬利器:scrapy-zyte-smartproxy 4. 智能调度:scrapy-thunder 5. 数据管道:scrapy…...
L3-21
exer01 Message # 1.定义Message消息类和cmd,content,sender,to四个属性,其中to默认为None class Message:def __init__(self, cmd, content, sender, toNone):self.cmd cmdself.content contentself.sender senderself.to to # 2. 创建登录消息对象msg1,聊天消…...
04.游戏开发-unity编辑器详细-工具栏、菜单栏、工作识图详解
04.游戏开发,unity编辑器详细-工具栏、菜单栏、工作识图详解 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是Python基础语法。前后每一小节的内容是存在的有:学习and理解的关联性,希…...
GRBL运动控制算法(二)圆弧插补
前言 GRBL 是一款高性能、开源的嵌入式 CNC(计算机数控)控制器固件,专为 Arduino 平台优化,广泛应用于雕刻机、激光切割机、3D 打印机及其他精密运动控制场景。自 2009 年发布以来,GRBL 凭借其高效的运动规划算法、稳…...
《P1072 [NOIP 2009 提高组] Hankson 的趣味题》
题目描述 Hanks 博士是 BT(Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。 今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数…...
矩阵分解中的梯度下降:详细实现方案(包含数学推导、代码实现和优化技巧)
矩阵分解中的梯度下降:详细实现方案(包含数学推导、代码实现和优化技巧) 矩阵分解是机器学习和数据科学中重要的技术,广泛应用于推荐系统、自然语言处理、图像处理等领域。梯度下降作为一种优化算法,在矩阵分解中常用于最小化目标函数以找到最佳的矩阵近似。本指南将详细…...
STM32F103C8T6实现 SG90 360 °电机转动
简介 基于上一篇 STM32F103C8T6实现 SG90 180 电机任意角度转动 本来想实现角度转动, 但靠舵机本身无法实现限位, 需要记录位置, 并且根据转速计算大概位置, 存在误差, 不实现角度转动了, 只实现正反转 代码 正向速度0.75为最大速度, 反向2.25, 接近1.5…...
RTDETR融合[CVPR2025]DnLUT中的MuLUTUnit模块
RT-DETR使用教程: RT-DETR使用教程 RT-DETR改进汇总贴:RT-DETR更新汇总贴 《DnLUT: Ultra-Efficient Color Image Denoising via Channel-Aware Lookup Tables》 一、 模块介绍 论文链接:https://arxiv.org/pdf/2503.15931 代码链接…...
大数据Spark(五十七):Spark运行架构与MapReduce区别
文章目录 Spark运行架构与MapReduce区别 一、Spark运行架构 二、Spark与MapReduce区别 Spark运行架构与MapReduce区别 一、Spark运行架构 Master:Spark集群中资源管理主节点,负责管理Worker节点。Worker:Spark集群中资源管理的从节点,负责任务的运行…...
二:python基础(黑马)
一:了解 1.1: python特点 python是完全面向对象的语言 函数,模块,数字,字符串都是对象,在python中一切皆对象 完全支持继承,重载,多重继承 支持重载运算符,也支持泛型设计 py…...
【马拉车 KMP 差分数组】P6216 回文匹配|省选-
本文涉及知识点 较难理解的字符串查找算法KMP C差分数组 马拉车算法 P6216 回文匹配 题目描述 对于一对字符串 ( s 1 , s 2 ) (s_1,s_2) (s1,s2),若 s 1 s_1 s1 的长度为奇数的子串 ( l , r ) (l,r) (l,r) 满足 ( l , r ) (l,r) (l,r) 是回文的&#…...
C/C++测试框架googletest使用示例
文章目录 文档编译安装示例参考文章 文档 https://github.com/google/googletest https://google.github.io/googletest/ 编译安装 googletest是cmake项目,可以用cmake指令编译 cmake -B build && cmake --build build将编译产物lib和include 两个文件夹…...
提高MCU的效率方法
要提高MCU(微控制器单元)的编程效率,需要从硬件特性、代码优化、算法选择、资源管理等多方面入手。以下是一些关键策略: 1. 硬件相关优化 时钟与频率: 根据需求选择合适的时钟源(内部/外部振荡器),避免过高的时钟频率导致功耗浪费。关闭未使用的外设时钟(如定时器、UA…...
Ansible 实战:Roles,运维的 “魔法函数”
一、介绍 你现在已经学过tasks和handlers,那么,最好的playbook组织方式是什么呢?答案很简单:使用roles!roles基于一种已知的文件结构,能够自动加载特定的vars_files、tasks以及handlers。通过roles对内容进…...
GO简单开发grpc
什么是grpc 首先我们需要了解,什么是grpc gRPC(全称:google remote procedure call)是由Google开发的一个高性能、开源的远程过程调用(RPC)框架。它基于 HTTP/2 协议,并且使用 Protocol Buffer…...
强引用,弱引用,软引用,虚引用,自旋锁,读写锁
强引用:强引用GC不会回收 软引用:内存够的话不回收,内存不够的话回收 弱引用:不管内存够不够,只要有GC就回收 虚引用:点get是null,但是GC后他会把引用放到引用队列里边 自旋锁:是指尝…...
C++异常处理 throw try catch
C 异常处理概述 C 异常处理机制提供了一种在程序运行时捕获错误或异常情况的方式。异常处理的目的是使得程序在遇到错误时能够优雅地终止或恢复,并防止程序出现崩溃。C 使用 try, throw, 和 catch 关键字来实现异常处理。 异常处理的基本结构: throw: …...
优化 Web 性能:管理第三方资源(Third-Party Summary)
在现代 Web 开发中,第三方资源(如分析工具、广告脚本、字体服务)为网站提供了丰富的功能,但也可能成为性能瓶颈。Google 的 Lighthouse 工具在性能审计中提供了“第三方资源概要”(Third-Party Summary)&am…...
第六章、 系统级 I/O
真题考点 考点一:Unix I/O 所有的 I/O 设备(例如网络、磁盘和终端)都被模型化为文件,而所有的输入和输出都被当作对相应文件的读和写来执行。这种将设备优雅地映射为文件的方式,允许 Linux 内核引出一个简单、低级的应用接口,称为…...
Jetpack Compose 自定义标题栏终极指南:从基础到高级实战
Jetpack Compose 自定义标题栏终极指南:从基础到高级实战 本文将带你彻底掌握 Compose 标题栏开发,涵盖 5 种专业级实现方案 性能优化技巧 完整可运行代码。 📚 核心方案对比 方案特点适用场景复杂度基础Row布局完全自定义,灵…...
晶晨S905-S905L-S905LB_S905M2通刷_安卓6.0.1_16S极速开机_线刷固件包
晶晨S905-S905L-S905LB_S905M2通刷_安卓6.0.1_16S极速开机_线刷固件包 线刷方法:(新手参考借鉴一下) 刷机工具版本请用2.2.0以上,导入固件后,刷机工具右侧两个擦除打勾,然后点开始。插上刷机神器…...
tkiner模块的初步学习
文章目录 一、前言二、概念2.1 安装2.2 窗口 三、小部件3.1 概述3.2 常用小部件3.2.1 Label3.2.2 Button3.2.3 Entry3.2.4 Text3.2.5 Listbox3.2.6 Checkbutton3.2.7 Radiobutton3.2.8 Scrollbar 3.3 更多小部件3.3.1 Scale3.3.2 Spinbox3.3.3. Progressbar 3.4 主题小部件 四、…...
Java常用数据结构操作方法全面总结
目录 一、List接口及其实现类二、Set接口及其实现类三、Map接口及其实现类四、Queue/Deque队列五、Stack栈六、树形结构七、注意事项与最佳实践总结 一、List接口及其实现类 核心实现类 ArrayList:基于动态数组LinkedList:基于双向链表 常用操作方法…...
Java的Selenium的特殊元素操作与定位之select下拉框
如果页面元素是一个下拉框,我们可以将此web元素封装为Select对象 Select selectnew Select(WebElement element); Select对象常用api select.getOptions();//获取所有选项select.selectBylndex(index);//根据索引选中对应的元素select.selectByValue(value);//选…...
STM32单片机入门学习——第15节: [6-3] TIM输出比较
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.05 STM32开发板学习——第15节: [6-3] TIM输出比较 前言开发板说明引用解答和科普一…...