美文网首页
图的遍历

图的遍历

作者: lxr_ | 来源:发表于2022-09-01 16:24 被阅读0次

图的遍历:

  • 从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traversing Graph)。
  • 树的遍历中由于根节点只有一个,遍历都是从根结点开始。但是图比较复杂,任一顶点都可能和其余的所有顶点相邻接,极有可能存在沿着某条路径搜索后,又回到原顶点,而有些顶点还没有遍历到。因此需要在遍历的过程中打上标记,避免同一个顶点访问多次,可以设置一个访问数组visited[n],n是图中顶点的个数,初值为false,访问过后设置为true。
  • 对于图的遍历来说,通常包括深度优先遍历(DFS)和广度优先遍历(BFS)两种方法。

深度优先遍历(Depth First Search,DFS):

从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到。对于非连通图,只需要对它的连通分量分别进行深度优先遍历,即在先前一个顶点进行一次深度优先遍历后,若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点做起始点,重复上述过程,直至图中所有顶点都被访问到位置。

广度优先遍历:(Breadth First Search,BFS):

我们可以发现图的深度优先遍历类似于树的前序遍历,而广度优先遍历类似于树的层序遍历。两者在存储结构相同的情况下时间复杂度是一样的,仅仅是对顶点访问的顺序不同。

代码示例

此处分别使用图的邻接矩阵和邻接表结构实现DFS和BFS,图的结构创建可查看https://www.jianshu.com/p/b50ba1b3c327
MGraph.h

//DFS(深度优先搜索遍历)
void DFS(MGraph G, int v);

//BFS(广度优先搜索遍历)
void BFS(MGraph G, int v);

MGraph.cpp

//DFS(深度优先搜索遍历,使用邻接矩阵的时间复杂度为O(n^2))
void DFS(MGraph G, int v)
{
    cout << G.vexs[v] << " ";
    visited[v] = true;                      //标志已经遍历过
    for (int i = 0; i < G.numVertexes; i++)
    {
        if (G.arc[v][i] && !visited[i])     //未遍历过的邻接点
        {
            DFS(G, i);                          //遍历第i个邻接点
        }
    }
}

//BFS(广度优先搜索遍历  O(n^2)---与存储结构相关)
void BFS(MGraph G, int v)
{
    cout << G.vexs[v] << " ";                           //先遍历当前顶点
    visited[v] = true;

    queue<int> q;
    q.push(v);

    while (!q.empty())                          //如果队列不为空
    {
        int u = q.front();                      //取队列第一个元素
        q.pop();                                //出队

        for (int i = 0; i < G.numVertexes; i++)
        {
            if (G.arc[u][i] && !visited[i])     //未遍历过的邻接点
            {
                cout << G.vexs[i] << " ";
                visited[i] = true;

                q.push(i);
            }
        }
    }
}

ALGraph.h

//DFS(深度优先搜索遍历)
void DFS(GraphAdjList G, int v);

//BFS(广度优先搜索遍历)
void BFS(GraphAdjList G, int v);

ALGraph.cpp

//DFS(深度优先搜索遍历)
void DFS(GraphAdjList G, int v)
{
    cout << G.adjList[v].data << " ";                       //输出顶点名称
    visited1[v] = true;

    EdgeNode* p = G.adjList[v].firstEdge;                   //顶点的第一条边
    while (p)
    {
        if (!visited1[p->adjvex])
        {
            DFS(G, p->adjvex);
        }
        p = p->next;
    }
}

//BFS(广度优先搜索遍历 O(n+e)--与存储结构相关 )
void BFS(GraphAdjList G, int v)
{
    cout << G.adjList[v].data << " ";                       //输出顶点名称
    visited1[v] = true;

    queue<int> q;
    q.push(v);

    EdgeNode* p;
    while (!q.empty())                                      //顶点还有邻接点
    {
        int u = q.front();
        q.pop();                                            //出队

        p = G.adjList[u].firstEdge;
        while (p)                                           //如果该顶点的边存在
        {
            if (!visited1[p->adjvex])
            {
                cout << G.adjList[p->adjvex].data << " ";
                visited1[p->adjvex] = true;
                q.push(p->adjvex);
            }
            p = p->next;
        }
    }
}

main.cpp

#include <iostream>
#include "MGraph.h"
#include "ALGraph.h"

using namespace std;

extern bool* visited, * visited1;

int main(int argc, char** argv)
{
    //1.邻接矩阵
    MGraph MG;
    CreateMGrah(MG);

    for (int i = 0; i < MG.numVertexes; i++)    //对于连通图,只执行一次
    {
        if (!visited[i])
        {
            DFS(MG, i);                         //深度优先搜索遍历
            //BFS(MG, 0);                       //广度优先搜索遍历
        }

    }

    //////////////////////////////////////////////////
    //2.邻接表
    GraphAdjList ALG;
    CreateALGraph(ALG);

    for (int i = 0; i < ALG.numVertexes; i++)   //对于连通图,只执行一次
    {
        if (!visited1[i])
        {
            DFS(ALG, i);
            //BFS(ALG, 0);
        }
    }
    return 0;
}

相关文章

  • 图的深度优先遍历

    数据结构遍历的意义 树的遍历 图的遍历 树的前序遍历 图遍历和树遍历区别 知识回顾 树的深度优先遍历 普通函数和递...

  • 图的深度优先遍历和马踏棋盘算法

    图的深度优先遍历思想 图的遍历通常有两种遍历次序方案: 深度优先遍历和广度优先遍历。深度优先遍历(DepthFir...

  • 图的DFS && BFS遍历

    对图的深度优先遍历: 对图的广度优先遍历:

  • 数据结构与算法学习-图的遍历

    图的遍历可以分为:深度优先遍历和广度优先遍历 一、深度优先遍历 深度优先遍历的实现思路 将图的顶点和边信息输⼊入到...

  • 图和遍历

    邻接矩阵定义一个图 其实就是二维数组来定义 图的遍历 深度搜索遍历 2.广度搜索遍历 遍历

  • 图 深度和宽度遍历

    图的深度遍历依赖于递归、 图的宽度优先遍历依赖于队列

  • 哈夫曼实现 图:十字链表,邻接多重链表,邻接表(无向),邻接表

    图的遍历: 无论是广度优先,还是深度优先都是以箭头方向右边的优先遍历; 广度优先遍历(无向图): 深度优先(无向图...

  • 11.图的广度优先遍历与无权图的最短路径

    图的广度优先遍历与无权图的最短路径 点击这里,前提知晓... 一、图的广度优先遍历 和树的广度优先遍历的思想一样,...

  • 基本数据结构

    一.图二.树 一.图 1.图的遍历: 通过深度优先遍历DFS和广度优先遍历BFS两种方式。深度优先遍历0 1 2 ...

  • 图的遍历

    树的遍历:从图中某一顶点出发,沿着一些边访问图中所有顶点,但使每个顶点仅被访问一次,这个过程叫做图的遍历。一个通常...

网友评论

      本文标题:图的遍历

      本文链接:https://www.haomeiwen.com/subject/tddsnrtx.html