深度优先搜索(DFS)与广度优先搜索(BFS)

图的遍历

    通常有两条遍历图的路径:深度优先搜索和广度优先搜索。它们对无向图和有向图都适用。

为了避免同一顶点被访问多次,在遍历过程中,必须记下每个已访问过的顶点。为此,我们可以设一个辅助数组 visited[0…n-1],它的初始值置为“假”或者0,一旦访问了顶点 vi,便置 visited[i] 为“真”或者为被访问时的次序号

用到的基本操作P:

  • FirstAdjVex(G,v);
    初始条件:图G存在,v是G中的某个顶点
    操作结果:返回v的第一个邻接顶点。若顶点在G中没有邻接顶点,则返回“空”
  • NextAdjVex(G,v,w);
    初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点
    操作结果:返回v的(相对于w的)下一个邻接顶点。若w是v的最后一个邻接顶点,则返回“空”

深度优先搜索

    深度优先搜索(Depth_ First Search)遍历类似于树的先序遍历过程。

  1. 从图中某顶点 v 出发,访问顶点v
  2. 依次从 v 的未访问的邻接点出发,继续对图进行深度优先搜索

例:求图G以V0为起点的深度优先序列
在这里插入图片描述

V0,V1,V3,V7,V4,V2,V5,V6

由于没有规定访问邻接点的顺序,访问结果不唯一

DFS算法

Boolean visited[MAX];       //访问标志数组
Status (*VisitFunc)(int v); //函数变量

void DFSTraverse(Graph G, Status (*Visit)(int v)) {
    /*对图G做深度优先遍历*/
    VisitFunc = Visit; //使用劝酒按量VisitFunc,使DFS不必设函数指针参数
    for (v = 0; v < G.vexnum; v++)
        visited[v] = FALSE; //访问标志数组初始化
    for (v = 0; v < G.vexnum; v++)
        if (!visited[v])
            DFS(G, v);
}

void DFS(Graph G, int v) {
    /*从第v个顶点出发递归地深度优先遍历图G*/
    visited[v] = TRUE;
    VisitFunc(v); //访问第v个顶点
    for (w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
        if (!visited[w])
            DFS(G, w); //对v的尚未访问的邻接顶点w递归调用DFS
}

广度优先搜索

    广度优先搜索(Broadth_ First Search)遍历类似于树的按层次遍历的过程。

  1. 从图中某未访问过的顶点 vi 出发,访问顶点 vi
  2. 访问 vi 的所有未被访问过的邻接点w1,w2,…,wk
  3. 依次从这些邻接点出发,访问它们的所有未访问过的邻接点,直到图中所有的顶点都被访问

例:求图G以V0为起点的广度优先序列
在这里插入图片描述
V0,V1,V2,V3,V4,V5,V6,V7

由于没有规定访问邻接点的顺序,访问结果不唯一

BFS算法

void BFSTraverse(Graph G, Status (*Visit)(int v)) {
    /*按广度优先非递归遍历图G,使用辅助队列Q和访问标志数组visited*/
    for (v = 0; v < G.vexnum; v++)
        visited[v] = FALSE; //访问标志数组初始化
    InitQueue(Q); //置空的辅助队列Q
    for (v = 0; v < G.vexnum; v++) {
        if (!visited[v]) { //v尚未访问
            visited[v] = TRUE;
            Visit(v);
            EnQueue(Q, v); //v入队列
            while (!QueueEmpty(Q)) {
                DeQueue(Q, u); //队头元素出队并置为u
                for (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) {
                    if (!visited[w]) { //w为u的未访问的邻接顶点
                        visited[w] = TRUE;
                        Visit(w);
                        EnQueue(Q, w);
                    } //if
                } //for
            } //while
        } //if
    } //for
} //BFSTraverse
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值