详解图的最短路径算法(BFS、Dijkstra、Floyd)(附上图解步骤)

图的最短路径

最短路径分为两种:
(1)单源路径:从某顶点出发,到其他全部顶点的最短路径
(2)顶点间的最短路径:任意两个顶点之间的最短路径
最短路径的结果主要有两个方面:
(1)顶点之间最短路径的长度
(2)从源顶点到目标顶点的路径

BFS

只有边权为 1 时才能用BFS求最短路。

为什么BFS能求边权为1的图的最短路呢?
其实可以把整个遍历路径看成一棵树
我们会看到是一层一层遍历的
也就是说 只要这个节点被访问到了,那么根节点到这个节点的最短路径就已经确定了


可以看到 2到1的最短路径就是1到6也是1
以此类推,2到8的最短路径就是3

从2出发,计算2到8的最短路径

第一步:初始化

在这里插入图片描述

d[i]=∞
path[i]=-1
d[2]=0 //2到自身的路径长度为0

1 2 3 4 5 6 7 8
d[] inf 0 inf inf inf inf inf inf
path[] -1 -1 -1 -1 -1 -1 -1 -1
1 2 3 4 5 6 7 8
visited F T F F F F F F
queue 2

第二步:从2出发,找到邻接点1、6
2出队 1、6进队

queue 1 6

在这里插入图片描述

path存的是当前节点的父节点,所以path[1] = 2 path[6] = 2

d[1] = d[2]+1 = 1
d[6] = d[2]+1 = 1

1 2 3 4 5 6 7 8
d[] 1 0 inf inf inf 1 inf inf
path[] 2 -1 -1 -1 -1 2 -1 -1
1 2 3 4 5 6 7 8
visited T T F F F T F F

第三步:节点1出队,找到邻接节点5
1出队 5进队

queue 6 5

d[5] = d[1]+1 = 2
path[5] = 1

在这里插入图片描述

1 2 3 4 5 6 7 8
d[] 1 0 inf inf 2 1 inf inf
path[] 2 -1 -1 -1 1 2 -1 -1
1 2 3 4 5 6 7 8
visited T T F F T T F F

第四步:节点6出队,找到邻接节点2、3、7
6出队 3、7进队,2访问过,忽略

queue 5 3 7

path[3] = 6
path[7] = 6
d[3] = d[7] = d[6]+1 = 2

在这里插入图片描述

1 2 3 4 5 6 7 8
d[] 1 0 2 inf 2 1 2 inf
path[] 2 -1 6 -1 1 2 6 -1
1 2 3 4 5 6 7 8
visited T T T F T T T F

第五步:节点5出队,没有邻接节点
5出队

queue 3 7

第六步:节点3出队,找到邻接节点6、4、7
3出队,4入队,6、7已经被访问过了 忽略

queue 7 4

d[4] = d[3]+1 = 2+1 = 3
path[4] = 3

在这里插入图片描述

1 2 3 4 5 6 7 8
d[] 1 0 2 3 2 1 2 inf
path[] 2 -1 6 3 1 2 6 -1
1 2 3 4 5 6 7 8
visited T T T T T T T F

第七步:节点7出队,找到邻接节点3、4、8
7出队,8入队,3、4已经被访问过了 忽略

queue 4 8

d[8] = d[7]+1 = 2+1 = 3
path[8] = 7

在这里插入图片描述

1 2 3 4 5 6 7 8
d[] 1 0 2 3 2 1 2 3
path[] 2 -1 6 3 1 2 6 7
1 2 3 4 5 6 7 8
visited T T T T T T T T

第七步:节点4出队,找到邻接节点3、7、8
3、7、8已经被访问过了 忽略

queue 8

第八步:节点8出队,找到邻接节点4、7
4、7、已经被访问过了 忽略

queue

至此,广搜结束,输出结果d[8] = 2

代码实现


const bfs = (graph,node)=>{
   
  const n = Object.keys(graph).length
  const visited = new Array(n+1).fill(false)
  const max = Number.MAX_SAFE_INTEGER
  const d = new Array(n).fill(max)
  const path = new Array(n+1).fill(-1)

  d[node] = 0
  visited[node] = true

  const queqe = [node]
  // 开始深搜
  while(queqe.length){
   
    const newnode =  queqe.shift()
    const v = graph[newnode]
    v&&v.map(item=>{
   
      // 这个节点没有访问过
      if(!visited[item]){
   
        path[item] = newnode
        d[item] = d[newnode]+1
        visited[item] = true
        queqe.push(item)
      }
    })

  }

  // 输出路径
  const rspath = [8]
  while(rspath[0]===node){
   
     rspath.unshift(path[rspath[0]])
  }

  console.log(rspath) // 2 6 7 8
  return d[8]  //3
}

const graph = {
   
  1:[2,5],
  2:[1,6],
  3:[6,7,4],
  4:[3,7,8],
  5:[1],
  6:[2,3,7],
  7:
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BFS(宽度优先搜索)算法常被用于解决迷宫问题中的最短路径问题。该算法基于队列的实现方式,可以快速搜索出从起点到达终点的最短路径。 具体来说,BFS算法步骤如下: 1. 创建一个队列,并将起点加入队列中。 2. 创建一个二维数组来记录迷宫中每个位置的状态,例如是否已被访问过或者是墙壁等。 3. 使用循环来遍历队列中的元素,直到队列为空。 4. 在循环中,首先从队列中取出一个节点,并标记该节点为已访问。 5. 然后检查该节点的上、下、左、右四个方向的相邻节点,如果相邻节点是可行的且未被访问过,则将其加入队列中,并记录其距离起点的步数。 6. 重复步骤4和步骤5,直到找到终点或者遍历完所有可行的节点。 7. 如果找到终点,则可以通过回溯找到最短路径。 需要注意的是,在BFS算法中,我们需要用一个二维数组来记录每个节点的状态,这样可以避免重复访问节点和处理墙壁等不可行的节点。 总结起来,BFS算法通过队列的方式,逐层遍历迷宫中的节点,直到找到终点。在遍历过程中,通过记录每个节点距离起点的步数,可以求解出最短路径。 参考文献: BFS 算法是一种基于队列实现的搜索算法,常用于解决图论问题和迷宫问题。 BFS(Breadth First Search,广度优先搜索)是一种基于队列实现的搜索算法,常用于解决图论问题和迷宫问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值