数据结构——图(6)——深入分析BFS算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/redRnt/article/details/82945571

DFS的不足和BFS算法

虽然我们知道根据DFS算法我们可以找到所有的,由起始节点到目标节点的所有路径,但并不代表那条路是最短的或者是最佳的。就像我们上篇文章所说的一样,对于同一幅图,非递归算法找到的路径就明显比递归算法找的要短。
回顾我们之前提到的BFS的基本思想:从起始顶点开始,首先探索邻居节点,然后再移动到下一级邻居。
在这里插入图片描述
假设我们从a走到i,按照BFS算法,应该是
a -> d-> h ->i (并且这是一条最短的路径
其BFS伪代码如下:

bfs from v1 to v2:
	//建立一个队列q来存储走过的路径path(可以用vector来存储路径)
    create a queue of paths (a vector), q
    //将节点v1的路径入队
    q.enqueue(v1 path)
    //当q不为空,并且节点V2未被访问时
    while q is not empty and v2 is not yet visited:
    //将q中的元素移出队列,并且存入path中
        path = q.dequeue()
        //将路径中的最后元素赋值给节点型变量v
        v = last element in path
        //如果v未被访问
        if v is not visited:
        //标记节点V
        mark v as visited
        //如果节点是目标节点,停止执行
        if v is the end vertex, we can stop.
        //遍历V中所有未被标记的邻居
        for each unvisited neighbor of v:
        //将v节点的邻居作为最后的元素构成新的路径
             make new path with v's neighbor as last element
             //将新的路径排入队列中
             enqueue new path onto q 


没错 这是一个很复杂的步骤。理解都有点困难更别提记住了,但是我们可以注意到,这个实现过程跟DFS的非递归实现是非常类似的。下面我们也是同样的分析一下实现过程:
还是从a到i,front指针指向队头。

  1. 先建立一个vector,用来存储路径,建立一个队列将路径装入:
Vector<Vertex  *> startPath
	startPath.add(a)
	q.enqueue(startPath)
  1. 此时队列中有元素a,已经访问的集合为空:
    在这里插入图片描述
    在这里插入图片描述
  2. 接下来到达循环语句:
in while loop:
   //将队列中的元素取出,放到当前路径的变量中
   curPath = q.dequeue() (path is a)
   //由于队列中只有一个元素a,所以它的最后元素也是它本身
   v = last element in curPath (v is a)
   //标记V
   mark v as visited
   //将所有的未标记的路径入队q中
   enqueue all unvisited neighbor paths onto q

这里注意,这里最后一句入队的是路径而不是节点,标记的才是及诶单。执行完毕后,队列跟访问集的情况如下:
在这里插入图片描述
在这里插入图片描述

  1. 此时队列不为空,直接从while循环开始。
in while loop:
   curPath = q.dequeue() (path is ab)
   v = last element in curPath (v is b)
   mark v as visited
   enqueue all unvisited neighbor paths onto q


根据队列的性质,FILO,所以最先出队列的是ab,ab路径中最后的元素是b,所以,标记b,并将b的所有邻居放入队列中去:
在这里插入图片描述
在这里插入图片描述

5.重复上述过程,直到路径中的最后的元素为目标元素 i 时,停止搜索。此时情况如下:

in while loop:
   curPath = q.dequeue() (path is adhi)
   v = last element in curPath (v is i)
   found!

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
此时的路径 a -> d-> h ->i 也是最短的路径

总结

在对于需要找到最短路径的图来说,BFS是绝佳的选择。广度优先搜索将查找从起始节点可到达的所有节点。
●它将按距离递增的顺序访问它们。
●在n节点m边图中,需要时间O(m + n)并使用空间O(n)。
●但在实践中,空间使用率远高于DFS。

这里有个有趣的问题,如果我们将BFS思想运用在树的遍历中会得到什么结论?得到一种我们熟悉的遍历方式。树中可是没有环的。

猜你喜欢

转载自blog.csdn.net/redRnt/article/details/82945571