图的遍历方法

图的遍历方法从图中某一顶点出发访遍图中其余顶点 且使每一个顶点仅被访问一次 这一过程就叫做图的遍历 TraversingGr 访问过的顶点打上标记 避免访问多次而不自知 可以通过设置一个访问数组 visited n n 是图中顶点个数 初值为 0 访问之后设置为 1 图遍历要避免因回路陷入死循环 通常有两种遍历次序方案 深度优先遍历广度优先遍历深度优先遍历深度优先遍历 Depth First Search 也有称为深度优先搜索 简称 DFS 如上图 如何从顶点 A 开始走遍所有的图顶点并作上标记 从顶点

从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traversing Graph)

访问过的顶点打上标记,避免访问多次而不自知;可以通过设置一个访问数组visited[n],n是图中顶点个数,初值为0,访问之后设置为1

图遍历要避免因回路陷入死循环,通常有两种遍历次序方案:

  • 深度优先遍历
  • 广度优先遍历

深度优先遍历

深度优先遍历(Depth_First_Search),也有称为深度优先搜索,简称DFS

image

如上图,如何从顶点A开始走遍所有的图顶点并作上标记?

从顶点A开始,始终向右手边走,注意,走到最后,还有一个I顶点没走。

深度优先遍历其实就是一个递归的过程,从图右边路径可以看出类似一棵树的前序遍历,确实如此。

从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径想通的顶点都被访问到。

非连通图,只需要对它的连通分量分别进行深度优先遍历,即在先前一个顶点进行一次深度优先遍历后,若图中尚有顶点未被访问,则选图中一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

邻接矩阵深度优先遍历

/ * 邻接矩阵的深度优先遍历(注意I点的遍历比较特殊) * @author jiaxinxiao * @date 2019年12月28日 */ public class DFSTest { Boolean[] visited = new Boolean[9]; //邻接矩阵的深度优先递归算法 void DFS(Graph graph,int i){ int j; visited[i] = true; System.out.println(graph.verxs[i]);//打印顶点,也可以进行其他操作 for(j = 0;j 
  

邻接表深度优先遍历

//邻接表深度优先递归算法 void DFS(GraphAdjList gl,int i){ EdgeNode p = null; visited[i] = true; System.out.println(gl.vertexNodes[i].data);//打印顶点 p = gl.vertexNodes[i].firstEdge; while(p != null){ if(!visited[p.next.adjvex]){ DFS(gl, p.next.adjvex); } p = p.next; } } //邻接表的深度遍历操作 void DFSTraverse(GraphAdjList gl){ int i; for(i = 0;i 
  

总结:两个不同存储结构深度优先遍历算法

  • 邻接矩阵是二维数组,要查找每个顶点的邻接点需要访问矩阵中的元素,因此需要O(n^2)的时间
  • 邻接表做存储结构,需要时间取决于顶点和边的数量,所以是O(n+e)

显然对于点多边少的稀疏图来说,邻接表结构使得算法在时间效率上大大提高。

广度优先遍历

广度优先遍历(Breadth First Search),又称广度优先搜索,简称BFS。

深度优先遍历未必是最佳方案,它意味着要彻底查找完一个地方,然后才查找另一个地方。

DFS类似于树的前序遍历,BFS类似于树的层序遍历。

image

如上图所示,顶点A作为第一层,A的所有边顶点BF作为第二层,BF的所有边顶点CIGE作为第三层,依次类推。

邻接矩阵广度优先遍历

//邻接矩阵广度遍历算法 void BFSTraverse(Graph g){ int i,j; Queue 
  
    q; for(i=0;i 
   
     (); for(i=0;i 
     
    
  

邻接表广度优先遍历

//邻接表广度遍历算法 void BFSTraverse(GraphAdjList g){ int i; EdgeNode p; Queue 
  
    q; for(i=0;i 
   
     (); for(i=0;i 
     
    
  

总结

两种遍历时间复杂度是相同的,不同的是对顶点的访问顺序不同。

两种算法没有优劣之分,视不同的情况选择不同的算法。

  • 深度优先更适合目标比较明确,以找到目标为主要目的的情况
  • 广度优先更适合在不断扩大遍历范围时找到相对最优解的情况
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215273.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午2:17
下一篇 2026年3月18日 下午2:17


相关推荐

  • ResultSet的遍历方法

    ResultSet的遍历方法ResultSet 遍历两种方法 第一 直接迭代 第二 用第三方工具类第一 直接迭代 1 DQL 代码不同于前面的 DML 过程的是 将原来的 sql 语句改成 DQL 并且调用 statement 的 executeQuery 方法执行查询 返回结果使用 ResultSet 进行接收 Stringsql select fromstudent ResultSetrs stm

    2026年3月18日
    1
  • 全网第一本Gemini 3与Nano Banana实战书重磅上市!

    全网第一本Gemini 3与Nano Banana实战书重磅上市!

    2026年3月15日
    3
  • java解析json转Map

    java解析json转Map前段时间在做json报文处理的时候,写了一个针对不同格式json转map的处理工具方法,总结记录如下:1、单节点单层级、单节点多层级json转mapimportjava.util.ArrayList;importjava.util.HashMap;importjava.util.Iterator;importjava.util.List;importjava.util.Map;i

    2022年6月15日
    73
  • pstack实现「建议收藏」

    pstack实现「建议收藏」注意,使用pstack查看系统进程的堆栈时需要sudo。注意第一行使用的bash,不可用dash。————————————#!/bin/bashiftest$#-ne1;then   echo”Usage:`basename$0.sh`”1>&2   exit1fiifte

    2025年11月18日
    4
  • C/C++中随机函数rand()和srand()的用法「建议收藏」

    C/C++中随机函数rand()和srand()的用法「建议收藏」一、rand()函数名:rand功能:随机数发生器用法:intrand(void);所在头文件:stdlib.h函数说明:rand()的内部实现是用线性同余法做的,它不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。

    2022年4月29日
    44
  • UltraEdit 许可证ID 如何加密和解密文本教程分享

    UltraEdit 许可证ID 如何加密和解密文本教程分享UltraEdit 是一款非常优秀的文本编辑器 功能丰富 易于使用 在处理文本时 大家有时候需要保护敏感数据 UltraEdit 的内置加密功能提供了一种快速 简单的加密 解密敏感数据的方法 让大家能够确保敏感数据的安全 从 V14 00 开始 可以使用内置的高级加密方法加密和解密文件 加密文件首先 需要使用 文件 打开 对话框浏览并打开需要的文件 打开需要加密的文件后 选择工具栏中 高级 加密 然后点击加密文件 在弹出的窗口中 需要选择 要加密的文件 密码 并且重复确认一次密码 需要注意

    2026年3月20日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号