【数据结构】2个例题带你理解图的遍历:广度优先搜索

简介: 【数据结构】2个例题带你理解图的遍历:广度优先搜索

1、定义


从图中的某个顶点v开始,先访问该顶点再依次访问该顶点的每一个未被访问过的邻接点 w1、w2、...


然后按此顺序访问顶点w1、w2、...的各个还未被访问过的邻接点。


重复上述过程,直到图中的所有顶点都被访问过为止。


练习1:从v0出发,写出它的按广度优先搜索进行遍历的遍历序列。


9471e341276c42aea29b2ef9ee6fc443.png


广度优先搜索过程:


27dcd45d4e394e01bac43848e060a09e.png


对于一个图,从某个顶点出发可得到多种搜索遍历结果,即一个图的BFS序列不唯一。


但给定起始点及图的存储结构时,BFS算法所给出的BFS序列是唯一的。


练习2:从v点出发,写出它的按广度优先搜索进行遍历的遍历序列。


4fb44b0396c34122b715ad6c60e54e4b.png


 广度优先搜索过程:


ee83160a889a4859b8fc22bd13b09ea9.png


2、算法分析


核心思想:使用队列记录所有的结点,只要进入到队伍,表示被访问。


b5b0a76baf1f467db10e8f7fc1c2692a.png


广度优先搜索遍历中,需要使用队列,依次记住被访问过的顶点,因此,算法开始时,访问起始点V,并将其插入队列中,以后每次从队列中删除一个数据元素,就依次访问它的每一个未被访问过的邻接点,并将其插入队列中。这样当队列为空的时候,表明所有与起始点相通的顶点都已被访问完毕,算法结束。


顶点的出队顺序,就是广度优先搜索遍历的序列。


3、算法实现


算法核心:


使用一个队列记录当前节点,所有未被访问的邻接点。


使用一个visited数组,记录顶点是否被访问。


public class BTraverser {
  private static boolean[] visited;// 访问标志数组
  // 对图G做广度优先遍历
  public static void BFSTraverse(IGraph G) throws Exception {
    visited = new boolean[G.getVexNum()];// 访问标志数组
    for (int v = 0; v < G.getVexNum(); v++)
      // 访问标志数组初始化
      visited[v] = false;
    for (int v = 0; v < G.getVexNum(); v++)
      if (!visited[v]) // v尚未访问
        BFS(G, v);
  }
  private static void BFS(IGraph G, int v) throws Exception {
    visited[v] = true;
    System.out.print(G.getVex(v).toString() + " ");
    LinkQueue Q = new LinkQueue();// 辅助队列Q
    Q.offer(v);// v入队列
    while (!Q.isEmpty()) {
      int u = (Integer) Q.poll();// 队头元素出队列并赋值给u
      for (int w = G.firstAdjVex(u); w >= 0; w = G.nextAdjVex(u, w))
        if (!visited[w]) {// w为u的尚未访问的邻接顶点
          visited[w] = true;
          System.out.print(G.getVex(w).toString() + " ");
          Q.offer(w);
        }
    }
  }
  public static void main(String[] args) throws Exception {
    ALGraph G = GenerateGraph.generateALGraph();
    BTraverser.BFSTraverse(G);
  }
}

4、性能分析


广度优先搜索遍历图的过程,实际上就是寻找队列中顶点的邻接点的过程。


假设图中有n个顶点和e条边


时间复杂度


当图的存储结构采用邻接矩阵时,需要扫描邻接矩阵的每一个顶点,其时间复杂度为O(n2)


当图的存储结构采用邻接表时,需要扫描邻接表中的每一个单链表,其时间复杂度为O(e)


空间复杂度


需要使用队列,依次记住被访问过的顶点,每一个顶点最多入队、出队一次,空间复杂度为O(n)


增设一个辅助数组visited,空间复杂度为O(n)。


相关文章
|
1月前
|
存储 编译器 C++
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
|
5月前
|
算法 C语言
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
|
25天前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
21 0
|
1月前
|
机器学习/深度学习 存储 算法
数据结构与算法——BFS(广度优先搜索)
数据结构与算法——BFS(广度优先搜索)
|
2月前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
3月前
【数据结构】遍历二叉树(递归思想)-->赋源码
【数据结构】遍历二叉树(递归思想)-->赋源码
50 4
|
4月前
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
38 1
|
5月前
|
算法 C语言
【数据结构与算法 经典例题】使用队列实现栈(图文详解)
【数据结构与算法 经典例题】使用队列实现栈(图文详解)
|
5月前
|
算法 C语言 计算机视觉
【数据结构与算法 经典例题】括号匹配问题
【数据结构与算法 经典例题】括号匹配问题
|
5月前
|
算法
【数据结构与算法 经典例题】随机链表的复制(图文详解)
【数据结构与算法 经典例题】随机链表的复制(图文详解)