图及其遍历

一些概念

· 图由顶点(Vertex)和边(Edge)组成,每条边的两端都必须是图的两个顶点
· 图可分为有向图和无向图,无向图的边都是双向的,可以当作正负向两条边组成
· 顶点的度是指和该顶点相连的边的条数。对于有向图来说,顶点的出边条数称为该定点的出度,入边条数则为入度
· 顶点和边的量化属性称为权值,点权和边权

图的存储

1.邻接矩阵

另二维数组G[N][N]的两维分别表示图的顶点标号,如果顶点i和j之间有边且i->j,则另G[i][j]=1(也可存边权),若为无向边则另G[i][j]也为1(或边权),若不存在边则为0
注:邻接矩阵只适用于顶点数目不太大(一般≤1000)的情况

2.邻接表

用vector实现会比较方便:

vector<int> V[N];     //存顶点编号

若要添加一条从顶点i到顶点j的有向边:

V[i].push_bach(j);

也可以同时存顶点编号和边权,自行创建结构体即可:

struct Node{
    int v,w;
};

则邻接表的定义更改为:

vector<Node> V[N];

添加从i到j的边权为x的有向边:

V[i].push_bach(Node{j,x});

图的遍历

几个概念
· 连通、连通图和连通分量
无向图中,如果从顶点i到j有路径,则称i与j连通,如果图中任意两个顶点之间都连通,则称该图为连通图;否则图中的极大连通子图称为连通分量。
· 强连通图和强连通分量
有向图中,若从i到j有路径,则称从i到j是连通的,如果对于每一顶点i和j,从i到j和从j到i都有路径,则称该图为强连通图;否则将其中的极大强连通子图称为强连通分量
(一般把连通分量和强连通分量统称为连通块)

1.深度优先搜索(DFS)遍历图

DFS伪代码如下:

DFS(u){           //访问顶点u
    vis[u]=true;      //设置u为已访问
    for(从u出发能到达的所有顶点v)
      if(vis[v]==false)    //如果v未访问
         DFS(v);          //递归访问v  ,此处访问深度+1
}
DFSTrave(G){     //遍历图G
    for(G的所有顶点u)
      if(vis[u]==false)
          DFS(u);       //访问u所在的连通块
                        //此处可一并操作数连通块个数
}     

2.广度优先搜索(BFS)遍历图

BFS伪代码如下:

BFS(u){
    queue q;     //定义队列 <int>/<node>/...
    将u入队;
    vis[u]=true;  //设置u为已访问
    while(q非空){
        取出q的队首元素u进行访问;
        for(从u出发能到达的所有顶点v)  //此处可更新层号
           if(vis[v]==false){
            将v入队;          
            vis[v]=true;
           }
    }
}
BFSTrave(G){
    for(G的所有顶点u)
      if(vis[u]==false)
        BFS(u);
}

具体实现需根据题意合理建立邻接矩阵或邻接表,设置变量类型为int或结构体元素或其他~

猜你喜欢

转载自blog.csdn.net/weixin_40984271/article/details/82560806