图的遍历
来源:互联网 发布:淘宝卖的奶粉是真的吗 编辑:程序博客网 时间:2024/06/05 12:08
图的遍历主要分为两种形式:广度优先遍历(BFS) 和深度优先遍历(DFS)。
对于图的遍历来说,不管是采用的邻接矩阵的方式,还是采用的邻接表的形式,其实现都是类似的,甚至可以说是一样的。
广度遍历
广度遍历利用了队列的特点,结点顺序的放入队列中,然后再出来。
对于采用邻接表还是邻接矩阵,两者实际上是非常类似的:
void BFSTraverse(MGraph G,Status(*Visit)(VertexType)){ /* 初始条件: 图G存在,Visit是顶点的应用函数。*/ /* 操作结果: 从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数 */ /* Visit一次且仅一次。一旦Visit()失败,则操作失败。 */ /* 使用辅助队列Q和访问标志数组visited */ int v,u,w; VertexType w1,u1; LinkQueue Q; 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; /* 设置访问标志为TRUE(已访问) */ Visit(G.vexs[v]); EnQueue(&Q,v); /* v入队列 */ while(!QueueEmpty(Q)) /* 队列不空 */ { DeQueue(&Q,&u); /* 队头元素出队并置为u */ strcpy(u1,*GetVex(G,u)); for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w)))) //对于采用邻接表还是邻接矩阵,主要的不同还是在于这里first,next 的实现的不同。 if(!visited[w]) /* w为u的尚未访问的邻接顶点的序号 */ { visited[w]=TRUE; Visit(G.vexs[w]); EnQueue(&Q,w); } } } printf("\n");
}
当时邻接表时,是:
(最后还有一个p=p->next)
如果是邻接矩阵,则是:
深度遍历
深度遍历完全可以理解为一个递归的过程。
void DFSTraverse(MGraph G,Status(*Visit)(VertexType)){ /* 初始条件: 图G存在,Visit是顶点的应用函数。*/ /* 操作结果: 从第1个顶点起,深度优先遍历图G,并对每个顶点调用函数Visit */ /* 一次且仅一次。一旦Visit()失败,则操作失败 */ int v; 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); /* 对尚未访问的顶点调用DFS */ printf("\n");}无论是邻接表还是邻接矩阵,这两者都是一样的。不同的是在DFS的部分。
void DFS(MGraph G,int v){ /* 从第v个顶点出发递归地深度优先遍历图G。*/ VertexType w1,v1; int w; visited[v]=TRUE; /* 设置访问标志为TRUE(已访问) */ VisitFunc(G.vexs[v]); /* 访问第v个顶点 */ strcpy(v1,*GetVex(G,v)); for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w)))) //不同的地方就在这里 if(!visited[w]) DFS(G,w); /* 对v的尚未访问的序号为w的邻接顶点递归调用DFS */}
对于不同的地方,还是在广度遍历中提到的部分。但是在这里,不同的地方还是完全一样的。跟上面的图完全一样。
这两种遍历算法在时间复杂度上是一样的。但是采用不同的存储结构所耗费的是不同的: 采用邻接矩阵,那么会因为搜索每个结点,那么对于需要n个顶点,e条边的图来说,需要O(n2),但是采用邻接表只需要O(n+e).
对于这两种遍历方法哪种会比较合适,这需要看情况了。如在大话数据结构总所说的:
- 图:图的遍历(深度优先遍历、广度优先遍历)
- java图的遍历方式(深度遍历、广度遍历)
- java图的遍历方式(深度遍历、广度遍历)
- 图的遍历(深度遍历和广度遍历)
- 图的遍历:深度优先遍历和广度优先遍历
- 图的 深度遍历 广度遍历
- 图的深度遍历和广度遍历
- 图的遍历(深度优先遍历)
- 图的遍历:深度优先遍历
- 图的遍历:宽度优先遍历
- 图的广度遍历和深度遍历
- 图的深度遍历和广度遍历
- 图的遍历-深度优先遍历
- 图的遍历-广度优先遍历
- 图的dfs遍历和bfs遍历
- 图的深度遍历和广度遍历
- 图的遍历算法-马遍历棋盘
- 图的遍历算法-马遍历棋盘
- 收集情报 发现问题 并要发现问题的本质与根源
- SqlServer查询数据库所有用户表的记录数
- C# 读写类操作xml文件
- Argo源码阅读(二):Controller的使用
- 利用oracle发送邮件功能简单监控数据库运行状态
- 图的遍历
- 我的Android进阶之旅------>Android实现数据存储技术
- mysql 慢查询配置
- 异常处理方法,同步VS异步
- 学习笔记之cocos2d-x2.1.1实现多个精灵的拖动
- 解决64位Linux系统编译32位错误
- linux ps命令参数和使用详解
- 关于SIGPIPE导致的程序退出
- IPRAN PTNRAN