图的遍历
来源:互联网 发布:刚玉的优化处理方法 编辑:程序博客网 时间:2024/06/01 08:10
从图中某一顶点出发访遍图中其与顶点,且使每一个顶点仅被访问一次,这一过程叫做图的遍历(Traversing Graph)。
对于图的遍历来说,如何避免回路陷入死循环,就要科学设计遍历方案,通常有两种:深度优先遍历和广度优先遍历。
深度优先遍历
深度优先遍历(Depth_First_Search),也称为深度优先搜索,简称DFS。深度优先遍历从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点触发深度优先遍历图,直到图中所有和v有路径相同的顶点都被访问到。(非连通图)若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。
其实深度优先遍历是一个递归的过程。下面详细介绍具体的代码实现:
typedef int Boolean; //布尔类型,true or falseBoolean visited[MAX]; //访问标志的数组/*邻接矩阵/邻接表的深度优先递归算法*/void DFS(MGraph G,int i){ //邻接表(GraphAdjList GL,int i) int j; //邻接表 EdgeNode *p; visited[i]=TRUE; printf("%c",G.vexs[i]); //邻接表 GL.adjList[i].data for(j=0;j<G.numVertexes;j++){ if(G.arc[i][j]==1&&!visited[j])//若两个结点有边且该结点未被访问 DFS(G,j); } /*邻接表 p=GL.adjList[i].firstedge //获取边表结点 while(p){ if(!visited[p->adjvex]) DFS(GL,p->adjvex); //对未访问的顶点递归 p=p->next; } */}/*邻接矩阵/邻接表的深度遍历操作*/void DFSTraverse(MGraph G){ //邻接表(GraphAdjList GL) int i; for(i=0;i<G.numVertexes;i++) //邻接表 GL->numVertexes visited[i]=FALSE; //初始化所有顶点为未访问状态 for(i=0;i<G.numVertexes;i++) //邻接表 GL->numVertexes //对未访问顶点调用DFS,若是连通图只会调用一次。 if(!visited[i]) DFS(G,i); //邻接表 DFS(GL,i);}
对比两种不同结构的深度优先遍历算法,对于n个点和e条边的图而言,邻接矩阵是二维数组,查找每个邻接点需要访问矩阵中的所有元素,所以时间复杂度为
广度优先遍历
广度优先遍历(Breadth_First_Search),也称为广度优先搜索,简称BFS。
若说图的深度优先遍历类似于树的前序遍历,则图的广度优先遍历就类似与树的层序遍历。下面详细介绍具体的代码实现:
/*邻接矩阵/邻接表的广度遍历操作*/void BFSTraverse(MGraph G){ //邻接表(GraphAdjList GL) int i,j; //邻接表 int i; EdgeNode *p; Queue Q; //队列 for(i=0;i<G.numVertexes;i++) //邻接表 GL->numVertexes visited[i]=FALSE; //初始化所有顶点为未访问状态 InitQueue(&Q); //初始化队列 for(i=0;i<G.numVertexes;i++) {//邻接表 GL->numVertexes if(!visited[i]){ //若未访问 visited[i]=TRUE; //打印顶点 printf("%c",G.vexs[i]); //邻接表 GL->adjList[i].data EnQueue(&Q,i); while(! QueueEmpty(Q)){ DeQueue(&Q,&i); for(j=0;j<G.numVertexes;j++){ /*判断其他定点若与当前结点存在边并未被访问过,入队列*/ if(G.arc[i][j]==1&&!visited[j]){ visited[j]=TRUE; printf("%c",G.vexs[j]); //打印顶点 EnQueue(&Q,i); } } /*邻接表 p=GL->adjList[i].firstedge; //当前顶点的边表头指针 while(p){ if(!visited[p->adjvex]){ //当前结点未被访问,入队 visited[p->adjvex]=TRUE; printf("%c",GL->adjList[p->adjvex].data); EnQueue(&Q,p->adjvex); } p=p->next; //指针指向下一邻接点 } */ } } }}
对比图的深度优先遍历还是广度优先遍历,发现,它们在时间复杂度上是一样的,不同之处仅在于对顶点访问顺序不同。相比较而言,深度优先更适合于目标比较明确,以找到目标为主要目的地情况;而广度优先遍历更适合在不断扩大遍历范围时找到相对最优解的情况。
0 0
- 图:图的遍历(深度优先遍历、广度优先遍历)
- java图的遍历方式(深度遍历、广度遍历)
- java图的遍历方式(深度遍历、广度遍历)
- 图的遍历(深度遍历和广度遍历)
- 图的遍历:深度优先遍历和广度优先遍历
- 图的 深度遍历 广度遍历
- 图的深度遍历和广度遍历
- 图的遍历(深度优先遍历)
- 图的遍历:深度优先遍历
- 图的遍历:宽度优先遍历
- 图的广度遍历和深度遍历
- 图的深度遍历和广度遍历
- 图的遍历-深度优先遍历
- 图的遍历-广度优先遍历
- 图的dfs遍历和bfs遍历
- 图的深度遍历和广度遍历
- 图的遍历算法-马遍历棋盘
- 图的遍历算法-马遍历棋盘
- -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased
- HDU 1212 Big Number (大数取模)
- C#基础-1:访问控制符、静态与非静态、参数传递
- android反编译
- oracle 11.2.0.4 physical standby failover
- 图的遍历
- 【记录】详解HTTP GET请求
- 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- POJ 1258 Agri-Net (最小生成树/Prim)
- Spring MVC 急速集成 Shiro 实录
- Java webSocket 网页聊天室
- 战争与和平 摘录一
- swift版本的图片轮播(借鉴于前辈的思路)
- 七牛evm主机主机快照和磁盘快照使用介绍