最短路径问题,BFS,408方向,思路与实现分析

最短路径问题,BFS,408方向,思路与实现分析

继上回挖下的坑,不知道大家有没有认真看最小生成树呢?很简单,这回也讲讲正常难度的,看不懂就来这里看看,讲的很好~~

最短路径问题

说起这个问题,先说个问题吧~~

这回不修路了,这回运东西哈哈哈,abcde五个城市,a是丝绸产业重地,那么经常要往,bcde4个城市运东西,那么到各个城市怎么运送距离最近呢?图示见下~~

图片

a分别到各个城市运送,这是一个单源最短路径问题~~

那么如果各个城市之间都有特产,需要相互的两两之间运送距离最近呢?这就是各顶点之间的最短路径问题~

所以明确一下,要搞的这三个算法当然是有适用范围的~~

图片

单源最短路径-BFS求无权图思路

BFS其实也就是广度优先遍历,图的广度优先遍历这里我们来模拟一下~~

当然,无权图你也可以想象成权值为一的特殊带权图嘛~~

图片

第一次遍历,我们访问的元素应该是1和6~~

第二次遍历,我们访问的元素应该是5,3和7~~

第三次遍历,我们访问的元素应该是4和8~~

图片

BFS代码实现与分析

先来代码~~

void BFS_MIN_Distance(Graph G,int u)
{
    
    for(i = 0;i < G.vexnum; ++i)
    {
     	d[i] =  false; //单源到各点路径长度的最短路径,先初始化,false代表不可到达
        path[i] = -1;  //最短路径从哪个顶点过来,先初始化
    }
    d[u] = 0;
    visited[u] =TRUE; //标记顶点u已被标记
    EnQueue(Q,u);//顶点u入队列
    while(!isEmpty(Q))//主过程
    {
        DeQueue(Q,u);//顶点u出队列
        for(w = FirstNeighbor(G,u); w >= 0; w = NextNeighbor(G,u,w))
        {	//遍历当前出队列的元素的所有邻接顶点,第一次为遍历顶点u的所有邻接顶点
            //当前出队列的元素即跳出for循环之后,再进入for循环时,本例中,u即为1号元素
            if(!visited[w]) //w为u为尚未访问的邻接顶点
            {
                d[w] = d[u] +1;//路径长度加1
                path[w] = u; //最短路径为u到w
                visited[w] = TRUE;//标记顶点w已被标记
                EnQueue(Q,w);//顶点w入队列
            }
        }
    }       
}

我们需要列出3块内容帮助我们分析~~

visited数组:

12345678
visitedfalsefalsefalsefalsefalsefalsefalsefalse

队:开始的时候没有元素~~

d[]和path[]数组

12345678
d[]falsefalsefalsefalsefalsefalsefalsefalse
path[]-1-1-1-1-1-1-1-1

分析一下到while主过程之前,我们做的事情~~

visited数组:

12345678
visitedfalsetruefalsefalsefalsefalsefalsefalse

队: 2 ,u为2

d[]和path[]数组

12345678
d[]false0falsefalsefalsefalsefalsefalse
path[]-1-1-1-1-1-1-1-1

那么此时进入while循环~~

第一次while循环,2出队~~

队: 空,此时2出队了~~

图片

进入for循环~~

第一次for,u为2,第一个邻接顶点为1,并且1尚未访问,所以路径长度加1,最短路径为u到w,即2到1,标记1已访问,1入队,w=NextNeighbor,还有邻接顶点,所以继续~~

第二次for,第二个u的邻接顶点,为6,并且6尚未访问所以路径长度加1,最短路径为u到w,即2到6,标记6已访问,6入队,w=NextNeighbor,没有邻接顶点了所以跳出~~

此时

visited数组:

12345678
visitedtruetruefalsefalsefalsetruefalsefalse

队: 1,6 ,队头为1,所以u为1

d[]和path[]数组

12345678
d[]10falsefalsefalse1falsefalse
path[]2-1-1-1-12-1-1

第二次while

1出队~~

进入for循环~~

图片

第一次for,u为1,第一个邻接顶点为2,但是2已被访问,所以不执行if内语句,w=NextNeighbor,还有邻接顶点,所以继续~~

第二次for,第二个u的邻接顶点,为5,5尚未访问所以路径长度加1,此时因为d[u]初始为1,所以为1+1=2,最短路径为u到w,即1到5,标记5已访问,5入队,w=NextNeighbor,没有邻接顶点了所以跳出~~

此时

visited数组:

12345678
visitedtruetruefalsefalsetruetruefalsefalse

队: 6 ,5,队头为6,所以u为6

d[]和path[]数组

12345678
d[]10falsefalse21falsefalse
path[]2-1-1-112-1-1

第三次while~~

6出队,再进行for循环,那么之后就会变成~~

visited数组:

12345678
visitedtruetruetruefalsetruetruetruefalse

队: 5,3,7队头为5,所以u为5

d[]和path[]数组

12345678
d[]102false212false
path[]2-16-1126-1

第四次whlie~~

5,出队,再进行for,没有邻接顶点,所以没有改变~~

visited数组:

12345678
visitedtruetruetruefalsetruetruetruefalse

队: 3,7队头为3,所以u为3

d[]和path[]数组

12345678
d[]102false212false
path[]2-16-1126-1

第五次while~~

3出队,进行for,此时~~

visited数组:

12345678
visitedtruetruetruetruetruetruetruefalse

队: 7队头为7,所以u为7

d[]和path[]数组

12345678
d[]1023212false
path[]2-163126-1

第六次whlie~~

7出队,进行for,此时~~

visited数组:

12345678
visitedtruetruetruetruetruetruetruetrue

队: 没有元素入队,队空了~~

d[]和path[]数组

12345678
d[]10232123
path[]2-1631267

此时队空,跳出while,执行成功~~

此时,我们得到了d[]和path[]数组~~

12345678
d[]10232123
path[]2-1631267

图片

比如我们看4号元素,即可知~~

2到4号元素的最短路径为长度d[4] = 3;

2到4号元素的最短路径为: 看4号元素path[4]为3,4 <- 3,再看3号元素path[3]为6,3 <- 6 ,再看6号元素path[6]为2,6 <- 2,所以2到4的最短路径为:2 -> 6 -> 3 -> 4~~

写到这才发现一写就挺多的,那Dijkstra,Floyd算法就下次再写咯~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZaunEkko

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值