浅析DFS与BFS的异同/图的和深度优先遍历和广度优先遍历有什么不同


浅析DFS与BFS的异同,图的和深度优先遍历和广度优先遍历有什么不同,DFS与BFS有什么区别?时间复杂度是多少?

一、深度优先遍历(DFS)

1.定义

图的深度优先搜索遍历(DFS)类似于二叉树的先序遍历。它的基本思想是:首先访问出发点v,
并将其标记为已访问过;然后选取与v邻接的未被访问的任意一个顶点w,并访问它:再选取与w邻接
的未被访问的任一项点并访问,以此重复进行。当一个顶点所有的邻接顶点都被访问过时,则依次退回到最近被访问过的顶点,若该顶点还有其他邻接顶点未被访问,则从这些未被访问的顶点中取一一个并重复上述访问过程,直至图中所有顶点都被访问过为止。图7-8所示即为一个图的深度优先搜索遍历过程。

在这里插入图片描述

图及定义摘自天勤,天勤no.1.

二、广度优先遍历(BFS)

1.定义

图的广度优先搜索遍历(BFS) 类似于树的层次遍历。它的基本思想是:首先访问起始顶点V,然
后选取与v邻接的全部顶点w,… w。进行访问,再依次访问与WI,… w。邻接的全部顶点(已经
访问过的除外),以此类推,直到所有顶点都被访问过为止。
广度优先搜索遍历图的时候,需要用到一一个队列(二叉树的层次遍历也要用到队列),算法执行过程
可简单概括如下:
1)任取图中一个顶点访问,入队,并将这个顶点标记为已访问;
2)当队列不空时循环执行:出队,依次检查出队顶点的所有邻接顶点,访问没有被访问过的邻接顶
点并将其入队;
3)当队列为空时跳出循环,广度优先搜索即完成。

三、异同

1.相同点

时间复杂度是相同的!
时间复杂度是相同的!
时间复杂度是相同的!
书上没有明确指明这一点,但是严奶奶的数据结构写到:
在这里插入图片描述
图源https://www.cnblogs.com/hi3254014978/p/12627861.html

2.不同点

(1)DFS

  1. 提供回溯,可以更新,完成并查集等算法
  2. 适用于有条件约束的问题,如棋盘问题
  3. 可以判断是否连通

(2)BFS

  1. 求最短路径
  2. 迷宫问题等

先挖个坑,有机会再逐渐补充完善。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用邻接矩阵表示无向,以及实现DFSBFS遍历的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_VERTEX_NUM 100 // 最大顶点数 // 邻接矩阵结构体 typedef struct { int vertex[MAX_VERTEX_NUM]; // 顶点数组 int edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 边的矩阵 int vertex_num; // 顶点个数 int edge_num; // 边的个数 } Graph; // 初始化 void init_graph(Graph *graph) { graph->vertex_num = 0; graph->edge_num = 0; for (int i = 0; i < MAX_VERTEX_NUM; i++) { graph->vertex[i] = 0; for (int j = 0; j < MAX_VERTEX_NUM; j++) { graph->edge[i][j] = 0; } } } // 添加顶点 void add_vertex(Graph *graph, int v) { graph->vertex[graph->vertex_num++] = v; } // 添加边 void add_edge(Graph *graph, int v1, int v2) { graph->edge[v1][v2] = 1; graph->edge[v2][v1] = 1; graph->edge_num++; } // DFS遍历 void dfs(Graph *graph, int v, bool *visited) { visited[v] = true; printf("%d ", graph->vertex[v]); for (int i = 0; i < graph->vertex_num; i++) { if (graph->edge[v][i] == 1 && !visited[i]) { dfs(graph, i, visited); } } } // BFS遍历 void bfs(Graph *graph, int v, bool *visited) { int queue[MAX_VERTEX_NUM]; int front = 0, rear = 0; visited[v] = true; printf("%d ", graph->vertex[v]); queue[rear++] = v; while (front < rear) { int cur = queue[front++]; for (int i = 0; i < graph->vertex_num; i++) { if (graph->edge[cur][i] == 1 && !visited[i]) { visited[i] = true; printf("%d ", graph->vertex[i]); queue[rear++] = i; } } } } int main() { Graph graph; init_graph(&graph); add_vertex(&graph, 0); add_vertex(&graph, 1); add_vertex(&graph, 2); add_vertex(&graph, 3); add_vertex(&graph, 4); add_edge(&graph, 0, 1); add_edge(&graph, 0, 2); add_edge(&graph, 1, 3); add_edge(&graph, 2, 4); bool visited[MAX_VERTEX_NUM] = {0}; printf("DFS遍历:"); dfs(&graph, 0, visited); printf("\nBFS遍历:"); for (int i = 0; i < MAX_VERTEX_NUM; i++) { visited[i] = false; } bfs(&graph, 0, visited); printf("\n"); return 0; } ``` 在上面的代码中,我们使用邻接矩阵来表示无向,其中`vertex`数组存储顶点,`edge`矩阵存储边。`add_vertex`函数用于添加顶点,`add_edge`函数用于添加边。`dfs`函数实现DFS遍历,`bfs`函数实现BFS遍历,`visited`数组用于标记已访问的顶点。在主函数中,我们创建了一个无向,并进行了DFSBFS遍历。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值