数据结构——图

文章目录

    • **一 图的基本概念**
      • **1 定义**
    • **二 图的存储及基本操作**
      • **1 邻接矩阵法**
      • **2 邻接表法**
      • **3 十字链表**
      • **4 邻接多重表**
      • **5 图的基本操作**
    • **三 图的遍历**
      • **1 广度优先搜索BFS**
      • **2 深度优先搜索DFS**
      • **3 图的遍历与连通性**
    • **四 图的应用**
      • **1 最小生成树**
        • **==1.1 Prim(普里姆)算法==**
        • **==1.2 Kruskal(克鲁斯卡尔)算法==**
      • **2 最短路径**
        • **==2.1 Dijkstra算法求单源最短路径问题==**
        • **==2.2 Floyd算法求各顶点直接最短路径问题==**
        • **2.3 有向无环图描述表达式**
        • **==2.4 拓扑排序==**
        • **==2.5 关键路径==**

一 图的基本概念

1 定义

图G由顶点集V和边集E组成,记为G=(V,E);|V|表示顶点个数,|E|表示边的条数

线性表可以是空表,树可以是空树,但是图不能是空图

(1)有向图

在这里插入图片描述

从顶点1到顶点2,1称为弧尾,2称为弧头

(2)无向图

没有方向的边

在这里插入图片描述

(3)简单图,多重图

简单图:不存在重复的边,不存在顶点到自身的边,如上面两图

多重图:某两个顶点直接的边数大于1条,又允许顶点通过一条边和自身相连

(4)完全图(简单完全图)

对于无向图,有n*(n-1)/2条边的无向图称为完全图,其任意两个顶点之间都存在边

对于有向图,有==n(n-1)==条弧的有向图称为有向完全图,其任意两个顶点之间都存在方向相反的两条弧

在这里插入图片描述

(5)子图

如有两个图G,G`,V’是V的子集,E‘是E的子集,则G’是G的子图

若V(G’)=V(G)的子图G’,则称其为G的生成子图

但不是任意子集都能构成子图,有些可能甚至不是图

(6)连通,连通图和连通分量

连通:无向图中,顶点v到顶点w有路径存在,则v和w连通的

连通图:图G中任意两个顶点都是连通的,否则称为非连通图

无向图中的极大连通子图称为连通分量

如果一个图有n个顶点,边数小于n-1,则必是非连通图;同理,如果图是非联通图,那么最多有n-2条边

在这里插入图片描述

(7)强连通图,强连通分量

强连通:有向图中,一对顶点v和w,从v到w和从w到v都有路径,称他们为强连通

强连通图:图中任何一对顶点都是强连通的

有向图中的极大强连通子图称为有向图的强连通分量

一个n个顶点的强连通图最少有n+1条边

在这里插入图片描述

(8)生成树,生成森林

连通图的生成树是包含图中全部顶点的一个极小连通子图,若有n个顶点,则含有n-1条边

去掉一个边就是非连通图,加一个边就形成回路

非连通图中,连通分量的生成树构成了非连通图的生成森林

在这里插入图片描述

极大连通子图:无向图的连通分量,要求该连通子图包含所有的边

极小连通子图:既要保持图连通,又要使得边数最少的子图

(9)顶点的度,入度和出度

无向图中,顶点v的度是指依附于v的边的条数,记为TD(v),每个顶点都要算一次,n条边就2n的度

有向图中,入度是以顶点v为终点的有向边的数目,记为ID(v),出度是以顶点v为起点的有向边的树,记为OD(v),度就是两者之和,且整个图的ID=OD=n(图的边数)

(10)边的权和网

每条边标上具有某种含义的数值称为该边的权值,这种带有权值的图称为带权图也称网

(11)稠密图,稀疏图

边数多就是稠密,少就是稀疏,是相对概念

(12)路径,路径长度和回路

顶点v到w经过的顶点序列就是路径,路径上的边就是路径长度,第一个顶点和最后一个顶点相同的路径成为回路或环

n个顶点,大于n-1条边的图一定有环

(13)简单路径,简单回路

简单路径:路径序列中顶点不重复出现

简单回路:除第一个顶点和最后一个顶点外,其余顶点不重复出现的回路

(14)距离

距离:顶点v到w的最短路径长度,不存在就标记为无穷

(15)有向树

一个顶点的入度为0,其余顶点的入度均为1的有向图

二 图的存储及基本操作

1 邻接矩阵法

指用一个一维数组存储图顶点信息,用一个二维数组存储图中边的信息

邻接矩阵:存储顶点直接邻接关系的二维数组

#define maxvertexnum 100         \\顶点数目
typedef char vertextype;         \\顶点的数据类型
typedef int edgetype;            \\带权图中边上权值的数据类型
typedef struct
{
    vertextype Vex[maxvertexnum];               \\顶点表
    edgetype Edge[maxvertexnum][maxvertexnum];  \\邻接矩阵,边表
    int vexunm,arcnum;                          \\当前顶点数和弧数
}

A[i][j]=10  表示从顶点i到j存在边就是1,否则是0
对带权图,A[i][j]=w 表示从i到j的权值是w,如不存在边就是0或者无穷

在这里插入图片描述

无向图的邻接矩阵是对称矩阵,并且唯一,可采用压缩存储;第i行非零元素的个数正好是顶点i的度

对有向图的第i行非零是i的出度,第i列非零是入度

邻接矩阵表示法的空间复杂度为O(n2),n是顶点数

要确定边数需要按行和列进行检测,时间慢,适合稠密图

邻接矩阵A,An的元素An[i][j]等于从i到j的长度为n的路径数目

2 邻接表法

对图的每个顶点vi建立一个单链表,第i个单链表中的结点表示依附于vi的边(对于有向图就是以vI为尾的弧),称为边表(对有向图就是出边表)

边表的头指针和顶点的数据信息采用顺序存储(顶点表),所以有顶点表结点和边表结点

在这里插入图片描述

#define maxvertexnum 100        \\顶点数目

typedef struct Arcnode          \\边表结点
{
    int adjvex;                 \\该弧指向顶点的位置
    struct Arcnode *next;       \\指向下一条弧的位置
    \\Infotype info;            \\边权值
}Arcnode;

typedef struct Vnode             \\顶点表结点
{
    Vertextype data;             \\顶点信息
    Arcnode *first;              \\指向第一条依附该顶点的弧的指针
}Vnode,Adjlist[maxvertexnum];

typedef struct
{
    Adjlist vertices;            \\邻接表
    int vexnunm,arcnum;          \\图的顶点数和弧数
}Algraph;

在这里插入图片描述

(1)无向图的存储空间为O(|v|+|2e|),有向图存储空间为O(|V|+|E|)

(2)适合稀疏图,极大的节省空间

(3)若要确定两个顶点间是否存在边,邻接矩阵可以直接查到,邻接表需要在相应的结点对应的边表中查找另一结点,效率较低

(4)有向图邻接表,顶点的出度只需看邻接表的结点个数,但是入度要查整个表

(5)链表次序不唯一

3 十字链表

十字链表中,对应有向图中的每条弧有一个结点,对应每个顶点也有一个结点

在这里插入图片描述

tailvex:指示弧尾顶点的编号

headvex:指示弧头顶点的编号

hlink:指向弧头相同的下一个弧结点

tlink:指向弧尾相同的下一个弧结点

info:存放弧的相关信息

弧头相同的就在同一个链表,弧尾相同的在同一个链表

data:顶点的数据信息

firstin:指向以该顶点为弧头的第一个弧结点

firstout:指向以该结点为弧尾的第一个弧结点

顶点结点之间顺序存储,很容易找到头和尾,即出入度

在这里插入图片描述

4 邻接多重表

无向图的另一种链式存储,每条边都用一个结点表示

在这里插入图片描述

ivex和jvex指示该边依附的两个顶点的编号;ilink指向下一条依附于顶点ivex的边,jlink指向下一条依附于顶点jvex的边;info存放边的相关信息

在这里插入图片描述

data:顶点信息

firstedge:指向第一条依附于该顶点的边

所有依附于同一顶点的边串联在同一链表中,每个边结点同时链接在两个链表中

在这里插入图片描述

5 图的基本操作

仅抽象考虑

Adjacent(G,x,y); \\判断G是否存在边<x,y>
Neighbors(G,x);  \\列出图G中与结点x邻接的边
Insertvertex(G,x);\\插入顶点x
Deletevertex(G,x);\\删除x
Addedge(G,x,y);   \\若边<x,y>不存在,则添加
Removeedge(G,x,y);\\若边<x,y>存在,则删除
Firstneighbor(G,x);\\求顶点x的第一个邻接点,有返回顶点号,没有或不存在x返回-1
Nextneighbor(G,x,y);\\y是x的一个邻接点,返回除y的下一个邻接点,没有返回-1
Get_edge_value(G,x,y);\\获取权值
Set_dege_value(G,x,y,v);\\设置边的权值为v                

三 图的遍历

1 广度优先搜索BFS

基本思想:访问起始结点v,从v出发,依次访问v的各个未访问过的邻接结点w1….wn,然后再依次访问w1….wn的所有未被访问过的邻接结点,然后再循环从结点出发,访问未被访问过的邻接结点,直到全部访问完毕

若还有没被访问的,重新选一个起始结点重复上述过程,直到全部访问完毕

dijkstra算法和prim最小生成树算法应用了这种思想

是一种分层的查找过程,类似树的层序遍历,需要借助队列,伪代码如下:

bool visited[maxvertexnum];              \\标记数组
void BFStraverse(Graph G)
{
    for(int i =0;i<G.vexnum;i++)         \\初始化标记数组
    {
        visited[i]=false;
    }
    Initqueue(Q);
    for(int i =0;i<G.vexnum;i++)        \\从0号顶点开始遍历
    {
        if(!visited[i])
        {
           BFS(G,i);                    \\每个连通分量一次BFS,没被访问过就BFS
        }
    }
}

void BFS(Graph G,int v)                   \\从v出发,遍历G
{ 
    visit(v);                             \\访问v
    visited[v]=true;                      \\置为true防止多次访问
    Enqueue(Q,v);                          \\v入队列
    while(!isempty(Q))                   
    {
        Dequeue(Q,v);                     \\v出队列
        for(w=Firstneighbor(G,v);w>=0; w=Nextneighbor(G,v,w))   \\检测v的所有邻接接点
        {
            if(!vitited[w])                   \\w为v未访问过的邻接接点
            {
                visit(w);       
                visited[w]=true;
                Enqueue(Q,w);                \\访问w后,w再入队列
            }
        }
    }
}

图的广度优先搜索和二叉树的层序遍历基本一致

BFS的算法性能分析

空间复杂度为O(|V|)

时间复杂度:(1)邻接表:O(|V|+|E|)

(2)邻接矩阵:O(|V|2)

BFS算法求解单源最短路径的问题

非带权图的最短路径d(u,v):从u到v的任何路径中最少的边数,没有则置为无穷

void BFSmindistance(Graph G,int u)
{
    \\d[i]表示u到i的最短路径
        for(int i =0;i<G.vextun;i++)
        {
            d[i]=;
        }
    visited[u]=true;d[u]=0;
    Enqueue(Q,u);
    while(!isempty(Q))
    {
        Dequeue(Q,u);                        \\队头元素u出队
        for(w =Firstneighbor(G,u); w>=0; w=Nextnrighbor(G,u,w))
        {
            if(!visited[w])                    \\w为u未访问的邻接结点
            {
                visited[w]=true;
                d[w]=d[u]+1;                  \\路径长度加1
                Enqueue(Q,w);
            }
        }
    }
}

广度优先生成树

遍历过程中可以得到一颗遍历树

邻接矩阵的树唯一,但是邻接表的不唯一

在这里插入图片描述

2 深度优先搜索DFS

类似树的先序遍历,尽可能“深”的搜索一个树

基本思想:访问起始顶点v,从v出发,访问与c邻接且未被访问的任意一个顶点w1,再访问与w1邻接且未被访问的任意一个顶点w2,重复这个过程,不能向下访问的时候,依次退回最近被访问的顶点, 若它还有未被访问的邻接顶点,则再从这个顶点开始搜索,直到图访问完毕

递归算法:

bool visited[maxvertexnum];
void DFStraverse(Graph G)
{
    for(int v=0 ;v<G.vextum;v++)
    {
        visited[v]=false;
    }
    for(int v = 0;v<G.vextum;v++)
    {
        if(!visited[v])
        {
            DFS(G,v);
        }
    }
}

void DFS(Graph G,int v)
{
    visit(v);
    visited[v]=true;
    for(w=Firstneighbor(G,v); w>=0; w=Nextneighbor(G,v,w))
    {
        if(!visited[w])
        {
            DFS(G,w);
        }
    }
}

DFS遍历的序列,邻接矩阵唯一,邻接表不唯一

DFS算法的性能分析

需要一个递归工作栈,空间复杂度为O(|V|)

时间复杂度:(1)邻接矩阵:O(|v|2)

(2)邻接表:O(|V|+|E|)

深度优先的生成树和生成森林

连通图调用DFS才能产生深度优先生成树,否则产生的是深度优先生成森林

3 图的遍历与连通性

无向图调用DFS,BFS的次数等于图的连通分量数

连通有向图分为强连通个非强连通,连通子图也分为强连通分量和非强连通分量

非强联分量一次调用BFS(G,i)或DFS无法访问到该连通分量的所有顶点

四 图的应用

1 最小生成树

一个带权连通无向图G,生成树不同,每棵树的权也可能不同,若T为权值之和最小的那颗生成树,则T为G的最小生成树MST

性质:

(1)最小生成树不唯一

(2)最小生成树的边的权值之和唯一

(3)最小生成树的边数为顶点数减1

根据性质从最小权值的边开始,基于贪心算法的有Prim和Kruskal算法

1.1 Prim(普里姆)算法

基本思想:任取一个顶点,找权值最小边并且不是重复顶点的边加入,直到所有顶点加入

n个顶点,T必有n-1条边

在这里插入图片描述

void Prim(G,T)
{
    T=;                           \\初始化空树
    U={w};                          \\添加任意一个顶点w
    while((V-U)!=)
    {(u,v)是使得u属于U与v属于(V-U),且权值最小的边;
        T=T∪{(u,v)};                \\边归入树
        U=U∪{v};                    \\顶点归入树
    }
}

时间复杂度:O(|V|2)

1.2 Kruskal(克鲁斯卡尔)算法

是一种按权值的递增次序选择合适的边来构造最小生成树的方法

在这里插入图片描述

void Kruskal(G,T)
{
    T=V;                           \\初始化T,仅含顶点
    numS=n;                        \\连通分量数,初始就是顶点总数
    while(numS>1)
    {
        从E中取权值最小的边(v,u)
        if((v,u)属于不同连通分量)
        {
             T=T∪{(u,v)};                \\边归入树
             numS--; 
        }
    }
}

时间复杂度:O(log2|E|)

2 最短路径

一个顶点到另一个顶点的路径的权值之和最短称为最短路径;两点直接的最短路径也包含了路径上其他顶点间的最短路径

单源最短路径:求图中某一顶点到其他各顶点的最短路径,可通过Dijkstra算法

每对顶点间的最短路径:Floyd算法求解

2.1 Dijkstra算法求单源最短路径问题

设置一个集合S记录已求得的最短路径的顶点,初始时把源点v0放入S,集合S每并入一个新顶点vi,都要修改源点v0到集合V-S中顶点当前的最短路径长度值。

设置两个辅助数组:

dist[]:记录源点v0到其他各顶点当前的最短路径长度,初态为:若从v0到vi有弧,则dist[i]为弧上的权值,否则置为无穷

path[]:path[i]表示从源点到顶点i之间的最短路径的前驱结点

初始S只包含顶点0;邻接矩阵arcs表示带权有向图,arcs[i] [j]表示边<i,j>的权值,不存在就置为无穷

算法步骤:

(1)初始化:S初始为{0},dist[i]=arcs[0] [i],i=1,2,3,……n-1

(2)从顶点集合V-S中选出vj,满足dist[j]=Min{dist[i]|vi ∈ \in V-S},vj就是当前求得的一条从v0出发的最短路径的终点,S=S ⋃ \bigcup {j}

(3) 修改从v0出发到集合V-S上任意一个顶点Vk可达的最短路径长度,若dist[j]+arcs[j] [k]<dist[k],则更新dist[k]=dist[j]+arcs[j] [k]

(4)重复2-3的操作n-1次,直到所有顶点都包含在S中,基于贪心策略

举例:

在这里插入图片描述

(1)初始化S,v1可达v2和v5,不可达v3和v4;故dist[2]=0,dist[3]=∞,dist[4]=∞;dist[5]=5

(2)选出最小值dist[5],将顶点v5并入集合S,此时找到1-5的最短路径;5加入后,1到集合V-S中可达顶点的最短路径长度可能会产生变化,更新dist[]数组,5可达2,1-5-2的距离8比dist[2]=10小,更新dist[2]=8;5可达3,1-5-3的距离14,更新dist[3]=14;5可达4,1-5-4的距离是7,更新dist[4]=7

(3)再选出最小值,dist[4],顶点4并入S,再更新dist[]数组;4不可达2,不变;4可达3,1-5-4-3距离是13比dist[3]小,更新dist[3]=13

(4)再选出最小的dist[2],顶点2并入S;更新dist[];2可达3,1-5-2-3的距离是9,比dist[3]小,更新dist[3]=9

(5)选出唯一的最小值dist[3],并入S,此时全部顶点并入完毕

无论是邻接矩阵还是邻接表的时间复杂度都是O(|V|2)

但是当边有负权值时,Dijkstra算法失效

在这里插入图片描述

例如图a,0到1和2的距离分别是7和5,那么就会首先并入顶点2,距离为5,再并入顶点1,但是并入顶点1时,从0到2的距离最小实际是2,不是5,但由于已经并入了2,无法更新

2.2 Floyd算法求各顶点直接最短路径问题

求出任意两个顶点i和j之间的最短路径和最短路径长度

基本思想:递推产生一个n阶方阵序列A(-1),A(0),A(1)……A(n-1),其中A(k)[i][j]表示从顶点i到顶点j的路径长度,k表示绕行第k个顶点的运算步骤。

初始时,任意两个顶点i和j直接存在边,则在边上的权值作为它们之间的最短路径长度;不存在有向边就用∞作为长度。

然后逐步尝试在原路径中加入顶点k作为中间顶点,若增加中间顶点后,得到的路径比原来的路径长度减少了,新路径就代替原路径

算法描述:

定义一个n阶方阵序列A(-1),A(0),A(1)……A(n-1),其中A(k)[i][j]=arcs[i] [j]

A(k)[i][j]=Min{A(k-1)[i][j],A(k-1)[i][k]+A(k-1)[k][j]},k=0,1……n-1

A(0)[i][j]是从顶点i到j,中间顶点是0的最短路径的长度;A(k)[i][j]是从顶点i到j,中间顶点的序号不大于k的最短路径的长度

这是一个迭代的过程,每迭代一次多考虑一个顶点;A(n-1)[i][j]就保存了任意一对顶点之间的最短路径长度

举例:

在这里插入图片描述

在这里插入图片描述

(1)初始化:方阵A(-1)[i][j]=arcs[i] [j]

(2)把0作为中间顶点,对所有顶点有A(-1)[i][j]>A(-1)[i][0]+A(-1)[0][j],把A(-1)[i][j]更新为A(-1)[i][0]+A(-1)[0][j];更新后方阵记为A0

(3)把1作为中间顶点,继续检测所有顶点,例如有A(0)[0][2]>A(0)[0][1]+A(0)[1][2]=10,更新,新方阵记为A1

(4)把2作为中间顶点,继续,更新方阵为A2,A2就是保存的任意顶点对的最短路径长度

时间复杂度:O(|V|3),但代码紧凑,对中等规模的输入来说仍然有效

允许图中有带负权值的边,但不允许与包含带负权值的边组成的回路;也适用于带权无向图

也可以用单源最短路径算法解决每对顶点之间的最短路径问题,轮流将每个顶点作为源点,在所有边权值均非负时,运行一次Dijkstra算法,时间复杂度为O(|V|3)

2.3 有向无环图描述表达式

若一个有向图不存在环,就成为有向无环图,简称为DAG图

例如((a+b)*(b*(c+d)+(c+d)*e))*((c+d)*e)

在这里插入图片描述

2.4 拓扑排序

AOV网:若用DAG图表示一个工程,其顶点表示工地,边表示活动i必须先于活动j进行的一种关系,则将这种有向图称为顶点表示活动的网络,边没有权值

拓扑排序:在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足以下条件时称为一个图的拓扑排序:

(1)每个顶点只出现一次

(2)若顶点A在序列中排在顶点B的前面,则在图中不存在从B到A的路径

拓扑排序是对有向无环图的的顶点的一种排序,使得若存在一条从顶点A到顶点B的路径,则在排序中顶点B出现在顶点A的后面,每个AOV网都有一个或多个拓扑排序序列

常见算法步骤:

(1)从AOV网中厕一个没有前驱的顶点输出

(2)删除该顶点和它为起点的有向边

(3)重复1,2直到没有顶点为止

在这里插入图片描述

bool Topologicalsort{Graph G}
{
    Initstack(S);
    int i ;
    for(i=0;i<G.vextum;i++)
    {
        if(indegree[i]==0)        \\所有入度为0的顶点入栈
        {
            Push(S,i);
        }
    }
    int count =0;                 \\记录当前输出的顶点数
    while(!isempty(S))
    {
        Pop(S,i);
        print[count++]=i;              \\输出顶点i
        for(p=G.vertices[i].firstarc; p ; p=p->nextarc) \\所有i执行的顶点的入度减1,并把入度为0的入栈
        {
            v=p->adjvex;
            if(!(--indegree[v]))
            {
                Push(S,v);             
            }
        }
    }
    if(count<G.vexnum)
        return false;                 \\有环路 失败
    else
        return true;
}

邻接表:O(|V|+|E|)

邻接矩阵:O(|V|2)

逆拓扑排序:

(1)选一个出度为0 的顶点输出

(2)删除顶点和它以它为终点的有向边

(3)重复1,2直到AOV网空

2.5 关键路径

AOE网:顶点表示事件,有向边表示活动,边的权值表示完成活动的开销,是有向无环图

性质:(1)只有某顶点的事件发生后,从该顶点出发的各有向边所代表的活动才能开始

(2)进入某顶点的各有向边的活动都结束时,该顶点代表的事件才发生

(3)仅有一个入度为0的顶点,称为开始顶点(源点);仅有一个出度为0的顶点,称为结束顶点(汇点)

(4)有些活动可以并行进行

(3)源点到汇点的所有路径中,具有最大路径长度的路径称为关键路径,关键路径的长度就是完成工程的最短时间

寻找关键活动的参量:

(1)事件vk的最早发生时间ve(k)

(2)事件vk的最迟发生时间vl(k)

(3)活动ai的最早开始时间e(i)

(4)活动ai的最迟开始时间l(i)

(5)一个活动ai的最迟开始时间l(i)和最早开始时间e(i)的差额d(i)=l(i)-e(i)

l(i)-e(i)=0,即活动aI是关键活动

算法步骤:

(1)从源点出发,ve(源点)=0,按拓扑有序求其余顶点的最早发生时间ve()

(2)从汇点出发,令vl(汇点)=ve(汇点),按逆拓扑有序求其余顶点的最迟发生时间vl()

(3)根据各顶点的ve()值求所有弧的最早开始时间e()

(4)根据各顶点的vl()值求所有弧的最迟开始时间l()

(5)求AOE网中的所有活动的差额d,找出所有d=0的活动构成关键路径

怎么求ve,ve就是从源点到这个点的耗时最长的数值

怎么求vl,从汇点倒着来,用汇点的值减去汇点到这个点的最小的值(尽量小的到达这个),所以vl ⩾ \geqslant ve

e就是弧起点的顶点的ve

l(i)等于该弧的终点的顶点的vl()减去弧的持续时间

在这里插入图片描述

关键路径上的所有活动都是关键活动

网中的关键路径并不唯一,只有加快所有关键路径上的关键活动才能缩短工期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/29261.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kendo UI for jQuery---03.组件___网格---02.开始

网格入门 本指南演示了如何启动和运行 Kendo UI for jQuery Grid。 完成本指南后&#xff0c;您将能够实现以下最终结果&#xff1a; 1. 创建一个空的 div 元素 首先&#xff0c;在页面上创建一个空元素&#xff0c;该元素将用作 Grid 组件的主容器。 <div id"my-…

Chat2DB:阿里巴巴开源的聊天数据管理工具--实践

Chat2DB&#xff1a;阿里巴巴开源的聊天数据管理工具–实践 简介 ​ Chat2DB 是一款有开源免费的多数据库客户端工具&#xff0c;支持windows、mac本地安装&#xff0c;也支持服务器端部署&#xff0c;web网页访问。和传统的数据库客户端软件Navicat、DBeaver 相比Chat2DB集成了…

Android音视频开发实战01-环境搭建

一,FFmpeg介绍 FFmpeg 是一款流行的开源多媒体处理工具&#xff0c;它可以用于转换、编辑、录制和流式传输音视频文件。FFmpeg 具有广泛的应用场景&#xff0c;包括视频编解码、格式转换、裁剪、合并、滤镜等等。官网:https://ffmpeg.org/ FFmpeg 支持各种常见的音视频格式&a…

计算机视觉-目标检测(二):从R-FCN到YOLO-v3

文章目录 1. R-FCN1.1 动机1.2. R-FCN 网络结构1.3. R-FCN 的损失函数1.4. R-FCN的训练及性能 2. YoLO-v12.1 简介2.2 YOLO-v1网络结构2.3 目标函数2.4 YOLO-v1的优缺点 3. YOLO-v23.1 YOLO-v2相比v1的优化 4. YOLO-v3参考 1. R-FCN 论文链接&#xff1a;R-FCN:Object Detecti…

在提交代码时有哪些注意事项

分享 10 种适合初学者的技术&#xff0c;这些技术将帮助您立即编写更好的代码。因此&#xff0c;如果您准备好将您的编码技能提升到一个新的水平&#xff0c;请继续阅读&#xff01; 1. 从计划开始 编写更好代码的最佳方法之一是从计划开始。在开始编码之前&#xff0c;请花几…

Nginx+Tomcat负载均衡、动静分离

Nginx应用 Nginx是一款非常优秀的HTTP服务器软件 支持高达50000个并发连接数的响应拥有强大的静态资源处理能力运行稳定内存、CPU等系统资源消耗非常低 目前很多大型网站都应用Nginx服务器作为后端网站程序的反向代理及负载均衡器&#xff0c;提升整个站点的负载并发能力 反向…

STM32 Proteu直流电机正反转控制系统限位开关-0035

STM32 Proteu直流电机正反转控制系统限位开关-0035 Proteus仿真小实验&#xff1a; STM32 Proteu直流电机正反转控制系统限位开关-0035 功能&#xff1a; 硬件组成&#xff1a;STM32F103C6单片机 L298N电机控制电路直流电机3个按键&#xff08;正转、反转、停止&#xff09;L…

Java企业级信息系统开发学习笔记(4.3) Spring Boot两种全局配置和两种注解

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/Z2viP】 文章目录 一、Application.properites配置文件1.1 创建Spring Boot的Web项目ProperitesDemo1.2 在应用属性文件里添加相关配置1. 配置服务器端口号和web虚拟路径2. 对象类型的配置与使用&…

【6.09 代随_52day】 最长递增子序列、最长连续递增序列、最长重复子数组

最长递增子序列、最长连续递增序列、最长重复子数组 最长递增子序列1.方法图解步骤递归代码 最长连续递增序列1.动态规划的方法图解步骤代码 最长重复子数组图解步骤代码 最长递增子序列 力扣连接&#xff1a;300. 最长递增子序列&#xff08;中等&#xff09; 1.方法 dp[i]…

【计算机网络自顶向下】如何学好计网-第二章应用层

第二章 应用层 应用层协议原理 网络应用程序体系结构 客户机/服务器体系结构&#xff1a;至少有一个服务器&#xff0c;一个客户机&#xff0c;其中服务器总是打开的&#xff0c;具有固定的众所周知的IP地址&#xff0c;主机群集常被用于创建强大的虚拟服务器&#xff0c;而客…

开发新项目看过来,这3款基于 Vue 的免费开源的 admin 管理后台框架非常好用

三款 admin 框架&#xff0c;分别基于热门的前端 UI 组件库 ElementPlus / Ant Design / Naive UI 打造&#xff0c;开箱即用。 新项目的开始&#xff0c;一般是搭建 admin 系统&#xff0c;今天盘点一下3个好的选择。 Vue vben admin 了解详细&#xff1a;https://www.thos…

数据建模学习2--作业-利用matlab解决实际问题

文章目录 Malthus模型问题用最小儿二乘法估计阻滞增长模型自来水运输问题利用 Dijkstra 算法计算下图中起点 D 至各顶点得最短距离&#xff0c;需要给出 仅供参考&#xff0c;代码注意修改 Malthus模型问题 1790-1980年间美国每隔10年的人口数量记录如下表所示。 表1 1790-1…

虚拟机(VMware )部署

一、VMware 概述&#xff1a; VMware是一家提供虚拟化解决方案的领先公司&#xff0c;其产品被广泛应用于企业和个人用户的计算环境中。VMware的虚拟化技术可以将物理计算资源&#xff08;如服务器、存储和网络&#xff09;抽象成虚拟化的资源&#xff0c;从而提供更高的灵活性…

kali学习笔记(二)

一、关闭自动锁屏 关闭自动锁屏对于测试人员来说&#xff0c;可以按照自己的习惯来设置&#xff0c;不然kali会过十分钟就锁屏&#xff0c;有的时候会比较不方便。 1、使用root账号登录&#xff0c;在display设置选项中做如下设置。 2、把休眠选项关掉。 二、创建快照 关机创…

算法刷题-数组-长度最小的子数组

209.长度最小的子数组 力扣题目链接 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0。 示例&#xff1a; 输入&#xff1a;s 7, …

React-Redux 对Todolist修改

在单独使用redux的时候 需要手动订阅store里面 感觉特别麻烦 不错的是react有一个组件可以帮我们解决这个问题, 那就是react-redux。 react-redux提供了Provider 和 connent给我们使用。 先说一下几个重点知道的知识 Provider 就是用来提供store里面的状态 自动getState()co…

MySQL——视图(VIEW)详解

今天我们一起来学起视图(VIEW)&#xff0c;那么视图是什么呢&#xff1f;视图有什么作用呢&#xff1f;视图一方面可以帮我们使用表的一部分而不是所有的表&#xff0c;另一方面也可以针对不同的用户制定不同的查询视图&#xff01;带着问题一起来寻找答案吧~~~ 1. 常见的数据库…

Zookeeper概述

​ ZooKeeper概述 ZooKeeper是什么 zookeeper是一个为分布式应用程序提供的一个分布式开源协调服务框架。是Google的Chubby的一个开源实现&#xff0c;是Hadoop和Hbase的重要组件。主要用于解决分布式集群中应用系统的一致性问题。提供了基于类似Unix系统的目录节点树方式的数…

python3 爬虫相关学习9:BeautifulSoup 官方文档学习

目录 1 BeautifulSoup 官方文档 2 用bs 和 requests 打开 本地html的区别&#xff1a;代码里的一段html内容 2.1 代码和运行结果 2.2 用beautiful 打开 本地 html 文件 2.2.1 本地html文件 2.2.2 soup1BeautifulSoup(html1,"lxml") 2.3 用requests打开 本地 h…

【默认端口】市面上各种中间件、软件、服务的默认端口汇总

常用软件&#xff0c;中间件&#xff0c;服务的默认端口汇总 常用软件默认端口汇总 市面上各种中间件、软件和服务的默认端口众多&#xff0c;下面列举一些常见的默认端口&#xff1a; SSH&#xff08;Secure Shell&#xff09;&#xff1a;22 Telnet&#xff1a;23 FTP…