(二) 图的遍历

(二) 图的遍历

1. 深度优先搜索 (Depth First Search, DFS)

[外链图片转存失败(img-MgjNKZTh-1567356455556)(C:\Users\alway\AppData\Roaming\Typora\typora-user-images\1567347155834.png)]

void DFS(Vertex v) {
	visited[v] = true;
    for (v的每个邻接点w) {
        if(!visited[w]) {
            DFS(w);
        }
    }
}

**注:**可用stack改递归为循环

**时间复杂度:**若有N个顶点,E条边

  • 用邻接表存储图, O ( N + E ) O(N+E) O(N+E)

  • 用邻接矩阵存储图, O ( N 2 ) O(N^2) O(N2)


2. 广度优先搜索 (Breadth First Search, BFS)

[外链图片转存失败(img-IjMMPRMt-1567356455557)(C:\Users\alway\AppData\Roaming\Typora\typora-user-images\1567347826519.png)]

void BFS(Vertex v) {
    visited[v] = true;
    Enqueue(v);
    while(!isEmpty(Q)) {
        v = Dequeue(Q);
        for (v的每个邻接点w) {
            if(!visited[w]) {
                visited[w] = true;
                Enqueue(w, Q);
            }
        }
    }
}

**注:**使用队列改递归为循环

时间复杂度:(同上)


3. 图不连通

**连通:**如果从v到w存在一条(无向)路径,则称v与w是连通的

**强连通:**如果从v到w存在双向路径,则称v与w是强连通的

**路径:**v到w的路径是一系列顶点的集合,且任一对相邻顶点间都有图中的边

**回路:**起点等于终点的路径

**连通图:**图中任意两顶点均连通

连通分量:无向图的极大连通子图

  • 极大顶点数:再加一个就不连通了

  • 极大边数:包含子图中所有顶点相连的所有边

    [外链图片转存失败(img-hftgLg0I-1567356455559)(C:\Users\alway\AppData\Roaming\Typora\typora-user-images\1567348540093.png)]

void ListComponents(Graph G) {
	for (each v in G) {
        if (!visited[v]) {
            DFS(V);
        }
    }
}

**注:**每调用一次DFS(v)就把v所在的连通分量遍历了一遍,BFS同理


4. 代码实现

  • 邻接表-DFS
/* 邻接表存储的图 - DFS */
 
void Visit( Vertex V )
{
    printf("正在访问顶点%d\n", V);
}
 
/* Visited[]为全局变量,已经初始化为false */
void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) )
{   /* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */
    PtrToAdjVNode W;
     
    Visit( V ); /* 访问第V个顶点 */
    Visited[V] = true; /* 标记V已访问 */
 
    for( W=Graph->G[V].FirstEdge; W; W=W->Next ) /* 对V的每个邻接点W->AdjV */
        if ( !Visited[W->AdjV] )    /* 若W->AdjV未被访问 */
            DFS( Graph, W->AdjV, Visit );    /* 则递归访问之 */
}
  • 邻接矩阵-BFS
/* 邻接矩阵存储的图 - BFS */
 
/* IsEdge(Graph, V, W)检查<V, W>是否图Graph中的一条边,即W是否V的邻接点。  */
/* 此函数根据图的不同类型要做不同的实现,关键取决于对不存在的边的表示方法。*/
/* 例如对有权图, 如果不存在的边被初始化为INFINITY, 则函数实现如下:         */
bool IsEdge( MGraph Graph, Vertex V, Vertex W )
{
    return Graph->G[V][W]<INFINITY ? true : false;
}
 
/* Visited[]为全局变量,已经初始化为false */
void BFS ( MGraph Graph, Vertex S, void (*Visit)(Vertex) )
{   /* 以S为出发点对邻接矩阵存储的图Graph进行BFS搜索 */
    Queue Q;     
    Vertex V, W;
 
    Q = CreateQueue( MaxSize ); /* 创建空队列, MaxSize为外部定义的常数 */
    /* 访问顶点S:此处可根据具体访问需要改写 */
    Visit( S );
    Visited[S] = true; /* 标记S已访问 */
    AddQ(Q, S); /* S入队列 */
     
    while ( !IsEmpty(Q) ) {
        V = DeleteQ(Q);  /* 弹出V */
        for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
            /* 若W是V的邻接点并且未访问过 */
            if ( !Visited[W] && IsEdge(Graph, V, W) ) {
                /* 访问顶点W */
                Visit( W );
                Visited[W] = true; /* 标记W已访问 */
                AddQ(Q, W); /* W入队列 */
            }
    } /* while结束*/
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值