【数据结构】图的遍历:广度优先(BFS),深度优先(DFS)

这篇具有很好参考价值的文章主要介绍了【数据结构】图的遍历:广度优先(BFS),深度优先(DFS)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、广度优先(BFS)

算法思想 

广度优先生成树 

知识树 

代码实现 

2、深度优先(DFS)

算法思想 

深度优先生成树

知识树 

代码实现 


1、广度优先(BFS)

算法思想 

         图的广度优先遍历(BFS)是一种遍历图的算法,其思想是从起始顶点开始遍历图,先访问起始顶点的所有直接邻居,然后遍历这些邻居的直接邻居,以此类推,直到遍历完整个图。

BFS算法需要使用一个队列来保存已经遍历过但还未访问其邻接顶点。具体步骤如下:

  1. 将起始顶点加入队列中,并标记为已访问。
  2. 从队列中取出一个顶点V,并依次访问V的所有未被访问的邻接顶点,并将这些邻接顶点加入队列中,并标记为已访问。
  3. 重复步骤2,直到队列为空。

广度优先生成树 

         广度优先搜索(BFS)可以用来生成一棵图的广度优先生成树(BFS树),该树的根节点为起始节点,其余节点按照宽度优先的顺序依次加入。BFS树可以用来解决最短路径问题,以及其他需要按照距离或层次访问节点的问题。

具体的实现步骤如下:

  1. 初始化BFS树,将起始节点加入树中。
  2. 将起始节点加入待访问队列。
  3. 对于队列中的每个节点,依次遍历其所有邻居节点。
  4. 对于每个邻居节点,如果该节点还未加入BFS树,则将其加入,并将该邻居节点的父节点设为当前节点。
  5. 将已访问的节点从队列中移除。
  6. 重复步骤3-5,直到队列为空。

知识树 

 bfs生成树,数据结构,数据结构,图的遍历,BFS,DFS

代码实现 

 下面是C语言实现BFS的示例代码:

#include <stdio.h>
#include <stdlib.h>

#define MAXV 100  // 最大顶点数

typedef struct {
    int edges[MAXV][MAXV];  // 邻接矩阵
    int n;  // 顶点数
} Graph;

typedef struct {
    int data[MAXV];
    int front, rear;
} Queue;

int visited[MAXV];  // 标记已经遍历的结点

void initQueue(Queue* q) {
    q->front = q->rear = 0;
}

void enqueue(Queue* q, int x) {
    q->data[q->rear++] = x;
}

int dequeue(Queue* q) {
    return q->data[q->front++];
}

int isEmpty(Queue* q) {
    return q->front == q->rear;
}

void initGraph(Graph* g, int n) {
    g->n = n;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            g->edges[i][j] = 0;
}

void addEdge(Graph* g, int u, int v) {
    g->edges[u][v] = 1;
    g->edges[v][u] = 1;
}

void bfs(Graph* g, int u) {
    Queue* q = (Queue*) malloc(sizeof(Queue));
    initQueue(q);
    visited[u] = 1;
    printf("%d ", u);
    enqueue(q, u);
    while (!isEmpty(q)) {
        int v = dequeue(q);
        for (int w = 0; w < g->n; w++) {
            if (g->edges[v][w] && !visited[w]) {
                visited[w] = 1;
                printf("%d ", w);
                enqueue(q, w);
            }
        }
    }
}

int main() {
    Graph g;
    int n, m, u, v;
    printf("输入顶点数和边数:");
    scanf("%d %d", &n, &m);
    initGraph(&g, n);
    printf("输入每条边的两个端点:\n");
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &u, &v);
        addEdge(&g, u, v);
    }
    printf("输入起始顶点:");
    scanf("%d", &u);
    printf("广度优先遍历结果:");
    bfs(&g, u);
    printf("\n");
    return 0;
}
 

        首先定义了一个邻接矩阵表示图,以及一个队列来存放待遍历的顶点。初始化队列为空,然后将起始顶点加入队列,并标记为已访问。然后开始遍历队列中的顶点,对于每个顶点,遍历其未访问的邻居,将其添加到队列中,并标记为已访问。代码中使用了visited数组来标记顶点是否已经被访问过了。

在以上代码中,输入格式为:

5 6
0 1
0 2
1 2
2 3
1 3
3 4
0
 

其中第一行为总顶点数和总边数,第2~m+1行为每条边的两个端点,然后输入起始顶点编号。

2、深度优先(DFS)

算法思想 

        图的深度优先遍历(Depth-First Search,DFS)是一种遍历图的算法。其基本思想是从一个顶点开始,沿着一条路径一直走到底,直到所有的路径都被探索过为止。如果还有顶点未被访问,则回溯到前一个顶点,继续搜索下一条路径,直到所有的顶点都被访问为止。

具体实现过程如下:
1. 从某一顶点开始遍历,将该顶点标记为已访问。
2. 对当前访问的顶点的所有未访问的邻接顶点进行访问,即从当前顶点的邻接顶点开始深度优先遍历。
3. 重复步骤2,直到所有的顶点都被访问。

        图的深度优先遍历可以用递归或栈来实现。在递归实现中,每次访问一个顶点时,递归地访问其未访问的邻接顶点,直到所有的顶点都被访问。在栈实现中,首先将起始顶点入栈,然后对栈内的顶点进行出栈、访问、入栈操作,直到所有的顶点都被访问。

深度优先生成树

        深度优先生成树(depth first search tree)是一棵以图中某个顶点为根的深度优先遍历树,它的生成过程为:

  1. 选择图中任意一个未被遍历的顶点作为根节点;
  2. 以根节点为起点进行深度优先遍历;
  3. 遍历到一个未被遍历的节点时,将该节点加入到生成树中,并将其父节点与该节点之间的边添加到生成树中;
  4. 如果图中还存在未被遍历的节点,则在剩余未被遍历的节点中选择一个节点作为新的根节点,并重复上述过程。

        生成树的过程可以通过递归实现,也可以使用栈来实现。在遍历的过程中,需要记录每个节点的状态,即已被发现、已被访问或未被发现。

知识树 

 bfs生成树,数据结构,数据结构,图的遍历,BFS,DFS

代码实现 

 以下是C语言中实现图的深度优先遍历的代码:

#include <stdio.h>
#include <stdbool.h>

#define MAX_VERTEX_NUM 100  // 顶点最大数量

typedef struct {
    int vertex;  // 顶点
    int next;    // 指向下一个邻接点的指针
} EdgeNode;

typedef struct {
    int vertex;      // 顶点
    EdgeNode *edge;  // 指向邻接点链表的指针
} VertexNode;

VertexNode graph[MAX_VERTEX_NUM];  // 图
bool visited[MAX_VERTEX_NUM];      // 记录哪些顶点已经被访问过

void addEdge(int v1, int v2) {
    // 添加边(v1, v2)
    EdgeNode *edge = graph[v1].edge;
    if (edge == NULL) {
        graph[v1].edge = (EdgeNode *) malloc(sizeof(EdgeNode));
        graph[v1].edge->vertex = v2;
        graph[v1].edge->next = -1;
    } else {
        while (edge->next != -1) {
            edge = graph[v1].edge + edge->next;
        }
        edge->next = graph[v1].edge - edge + addEdge(v2, -1);
    }
}

void dfs(int vertex) {
    visited[vertex] = true;
    printf("%d ", vertex);

    EdgeNode *edge = graph[vertex].edge;
    while (edge != NULL) {
        int nextVertex = edge->vertex;
        if (!visited[nextVertex]) {
            dfs(nextVertex);
        }
        edge = graph[vertex].edge + edge->next;
    }
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);  // n表示顶点数,m表示边数

    for (int i = 1; i <= n; i++) {
        graph[i].vertex = i;
    }

    for (int i = 0; i < m; i++) {
        int v1, v2;
        scanf("%d %d", &v1, &v2);
        addEdge(v1, v2);
        addEdge(v2, v1);  // 在无向图中,边(v1, v2)和边(v2, v1)都要添加
    }

    memset(visited, false, MAX_VERTEX_NUM);  // 初始化visited数组

    printf("DFS: ");
    dfs(1);  // 从顶点1开始进行DFS

    return 0;
}
 

        其中addEdge函数用于添加一条边。在main函数中,先读入图的顶点数和边数,然后依次读入每条边,并调用addEdge函数添加边。最后,初始化visited数组为false,并从顶点1开始进行深度优先遍历。文章来源地址https://www.toymoban.com/news/detail-759872.html

到了这里,关于【数据结构】图的遍历:广度优先(BFS),深度优先(DFS)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (超详细)C++图的深度优先遍历、广度优先遍历(数据结构)

            根据下图,编写代码实现图的深度优先遍历和广度优先遍历。          按照英文字母顺序,以邻接表为存储结构,实现图的深度优先和广度优先遍历。遍历的顺序从顶点a开始。 以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。   (1)从顶点a,

    2024年02月08日
    浏览(47)
  • 【数据结构与算法】图的深度优先和广度优先遍历

    😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享Java相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页 ✨✨座右铭✨✨ : 坚持到底,决不放弃,是成功的保证,只要你不放弃,你就有机会,只要放弃的人,他肯定是不会成功的人。 图是一

    2024年02月02日
    浏览(46)
  • 【数据结构】图的创建(邻接矩阵,邻接表)以及深度广度遍历(BFS,DFS)

    图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E),其中: 顶点集合V = {x|x属于某个数据对象集}是有穷非空集合; E = {(x,y)|x,y属于V}或者E = {x, y|x,y属于V Path(x, y)}是顶点间关系的有穷集合,也叫 做边的集合。 完全图:在有n个顶点的无向图中,若有n * (n-1)/2条边,

    2024年02月04日
    浏览(31)
  • 数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

      图采用邻接表存储结构,编程实现图的深度优先搜索和广度优先搜索算法。              2.1创建图 2.1.1定义图的顶点、边及类定义   我们定义一个 邻接表类(ALGraph) 。这里实现一些基础的数据结构。要注意结构体的嵌套。    Edge: 用于表示图中的边

    2024年02月04日
    浏览(34)
  • 数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)

    图的遍历指从图中某一顶点出发(任意一个顶点都可以作为访问的起始顶点),按照某种遍历方法,对图中所有的顶点访问一次且只访问一次。图与树不一样,其中一个顶点可能与多个顶点相连,所以需记录已访问过的顶点,当访问一个顶点后,考虑如何选取下一个要访问的

    2024年02月05日
    浏览(37)
  • 【数据结构与算法】图的基本概念 | 邻接矩阵和邻接表 | 广度优先遍历和深度优先遍历

    🌠 作者:@ 阿亮joy. 🎆 专栏:《数据结构与算法要啸着学》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E) ,其中: 顶点集合V = {x|x属于某

    2024年02月04日
    浏览(56)
  • 图的遍历(广度优先遍历BFS,深度优先遍历DFS)

    目录 图的遍历概念: 图的广度优先遍历(BFS): 代码实现如下: 测试如下: 注意: 图的深度优先遍历(DFS): 代码实现如下: 测试如下: 总代码: 结语: 给定一个图G和其中任意一个顶点v0,从v0出发,沿着图中各边访问图中的所有顶点,且每个顶点仅被遍历一次。\\\"遍

    2024年02月21日
    浏览(38)
  • 【数据结构】广度优先遍历(BFS)模板及其讲解

    🎊专栏【数据结构】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【勋章】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录   🎁定义 🎁遍历方法  🎁根据题目来理解BFS 🏳️‍🌈走迷宫 🏳️‍🌈思路 🏳️‍🌈代码(BFS模板) 🏳️‍🌈分

    2024年02月06日
    浏览(30)
  • 【数据结构】图的广度优先遍历

    广度优先遍历,类似于树的层次遍历,又是熟悉的队列实现。首先将第一个顶点添加到队列中,然后讲该顶点的所有邻接顶点都加入队列中,再将该顶点输出。如此重复直到遍历完整个图。 Q:队列,用于存放顶点。 front,rear:队头和队尾指针,用于入队和出队。 p:工作指针,用

    2024年02月05日
    浏览(32)
  • 数据结构--5.3图的遍历(广度优先遍历)

    广度优先遍历:         广度优先遍历(BreadthFirstSearch),又称为广度优先搜索,简称BFS。 要实现对图的广度遍历,我们可以利用队列来实现。  (参考队列)(上述为结构)

    2024年02月10日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包