图算法三之BFS
来源:互联网 发布:淘宝佣金是多少 编辑:程序博客网 时间:2024/05/01 11:39
如果说图的深度优先遍历类似树的前序遍历, 那么图的广度优先遍历就类似于树的层序遍历了,其实我就是按照树的层次遍历来理解图的BFS,因为这样容易记忆还方便理解
BFS也贴个图吧
代码也不长,感觉和DFS一样,都是侧重于理解,理解了代码就能写出来了
先是邻接矩阵的BFS
void MGraphBFS(int i,struct MGraph *graph){queue<int> queue;flag[i] = 1;queue.push(i);while(queue.size()){int current = queue.front();printf("%d ",current);queue.pop();for(i=0;i<graph->numVertexes;i++){if(!flag[i]&&graph->arc[current][i]!=INFINITY){flag[i] = 1;queue.push(i);}}}}然后是邻接表的BFS
void LGraphBFS(int i,struct LGraph *graph){queue<int> queue;flag[i] = 1;queue.push(i);while(queue.size()){int current = queue.front();printf("%d ",current);queue.pop();struct EdgeNode *e = graph->adjList[current].firstarc;while(e){if(!flag[e->adjex]) {flag[e->adjex] = 1;queue.push(e->adjex);}e = e->next;}}}最后总结一下,感觉大话数据结构总结得挺好,就copy了
对比图的深度优先遍历与广度优先遍历算法,你会发现,它们在时间复杂度上是一样的,不同之处仅仅在于对顶点访问的顺序不同。可见两者在全图遍历上是没有优劣之分的,只是视不同的情况选择不同的算法。
不过如果图顶点和边非常多,不能在短时间内遍历完成,遍历的目的是为了寻找合适的顶点,那么选择哪种遍历就要仔细斟酌了。深度优先更适合目标比较明确,以找到目标为主要目的的情况,而广度优先更适合在不断扩大遍历范围时找到相对最优解的情况。
这里还要再多说几句,对于深度和广度而言,已经不是简单的算法实现问题,完全可以上升到方法论的角度。你求学是博览群书、不求甚解,还是深钻细研、鞭辟入里;你旅游是走马观花、蜻蜓点水,还是下马看花、深度体验;你交友是四海之内皆兄弟,还是人生得一知己足矣……其实都无对错之分,只视不同人的理解而有了不同的诠释。我个人觉得深度和广度是既矛盾叉统一的两个方面,偏颇都不可取,还望大家自己慢慢体会。
最后,总的代码如下:
#include <stdio.h>#include <stdlib.h>#include <iostream>#include <queue>using namespace std;#define MAXN 100#define INFINITY 65536bool flag[MAXN];struct MGraph{int numEdges,numVertexes;int vex[MAXN];int arc[MAXN][MAXN];};struct EdgeNode{int weight;int adjex;struct EdgeNode *next;};struct VexNode{int data;struct EdgeNode *firstarc;};struct LGraph{int numEdges,numVertexes;struct VexNode adjList[MAXN];};void createMGraph(struct MGraph *graph){printf("请输入图的总顶点数和边数:\n");scanf("%d%d",&graph->numVertexes,&graph->numEdges);int i,j,k;for(i=0;i<graph->numVertexes;i++){for(j=0;j<graph->numVertexes;j++){graph->arc[i][j] = INFINITY; }}for(i=0;i<graph->numVertexes;i++){graph->vex[i] = i;}for(k=0;k<graph->numEdges;k++){printf("请输入(vi,vj)的下标i和j\n");scanf("%d%d",&i,&j);graph->arc[i][j] = graph->arc[j][i] = 1;}}//对存储结构为邻接矩阵的图进行BFSvoid MGraphBFS(int i,struct MGraph *graph){queue<int> queue;flag[i] = 1;queue.push(i);while(queue.size()){int current = queue.front();printf("%d ",current);queue.pop();for(i=0;i<graph->numVertexes;i++){if(!flag[i]&&graph->arc[current][i]!=INFINITY){flag[i] = 1;queue.push(i);}}}}void createLGraph(LGraph *graph){printf("请输入图的顶点数和边数\n");scanf("%d%d",&graph->numVertexes,&graph->numEdges);int i,j,k;for(i=0;i<graph->numVertexes;i++){graph->adjList[i].data = i;graph->adjList[i].firstarc = NULL;}for(k=0;k<graph->numEdges;k++){printf("请输入(vi,vj)的下标i和j\n");scanf("%d%d",&i,&j);struct EdgeNode *e = (struct EdgeNode *)malloc(sizeof(struct EdgeNode));e->adjex = j;e->next = graph->adjList[i].firstarc;graph->adjList[i].firstarc = e;e = (struct EdgeNode *)malloc(sizeof(struct EdgeNode));e->adjex = i;e->next = graph->adjList[j].firstarc;graph->adjList[j].firstarc = e;}}//对存储结构为邻接表的图进行BFSvoid LGraphBFS(int i,struct LGraph *graph){queue<int> queue;flag[i] = 1;queue.push(i);while(queue.size()){int current = queue.front();printf("%d ",current);queue.pop();struct EdgeNode *e = graph->adjList[current].firstarc;while(e){if(!flag[e->adjex]) {flag[e->adjex] = 1;queue.push(e->adjex);}e = e->next;}}}int main(){MGraph graph;createMGraph(&graph); MGraphBFS(0,&graph); //都是建立的连通图,所以不需要循环了,只需要从0开始调用int i;for(i=0;i<MAXN;i++) flag[i] = 0;LGraph lgraph;createLGraph(&lgraph);LGraphBFS(0,&lgraph);return 0;}
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权
0 0
- 图算法三之BFS
- 算法之路(三)——BFS
- 图算法之bfs/dfs
- 图算法之bfs、dfs、prim、Dijkstra
- C++--图算法之DFS,BFS,Dijstra
- 图算法一之广度搜索(bfs)
- 算法入门之BFS
- 十二周 项目三 图遍历算法实现(BFS)
- BFS算法之求单源最短路径
- 基础算法 之 BFS & DFS
- 第十二周项目三 图遍历算法实现——广度优先(BFS)遍历
- 【算法模板之DFS和BFS】
- 算法笔记之DFS与 BFS
- 算法题:BFS之出门最佳
- 二分图(bfs+匈牙利算法)
- 图的BFS,DFS算法
- 冬令营之算法三
- DFS算法,BFS算法遍历图
- Struts,JSP和XML解析三个问题
- valgrind-运行时诊断工具Memory Leak Check Tool
- •Web 服务器上的请求筛选被配置为拒绝该请求,因为查询字符串过长。
- 多线程GCD的使用
- 图算法三之BFS
- 我们都曾回不到的过去就这样慢慢地淡下来了
- Git远程操作详解
- linux脚本的几种执行方式
- List view 和 RichTextBox
- C++学习心得
- JS获取IP、MAC和主机名的五种方法
- 字符串的移动
- Hibernate进阶之熟悉Hql