数据结构第七周笔记(4)——图(中)(慕课浙大版本--XiaoYu)

75 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情

7.1 最短路径问题

7.1.1 概述

a点到b点之间路径可达最短的一条线路就是最短路径
​
或者说是从a点到b点最省钱的路线,这也是一种最短路的问题 ->这种情况下什么是长什么是短?
    //区别就在边上的权重(我们赋予了他们什么意义),比如我们要找最便宜的路径,那么两点之间的那个边的权重就应该定义成票的价格
    //我们要找的就是票的价格的和是最小的那条路
假如我们要找的是a站点到b站点最快的那个路径,这时候什么叫快?
    //是 经停的站最少的快 还是说 途经时间最短的快。在这里我们选择前者
    //这时候边的权重就定义为1,经停站的个数就是每条边加起来的了

最短路径问题的抽象

在网络中,求两个不同顶点之间的所有路径中,边的权值之和最小的那一条路径

  1. 这条路径就是两点之间的最短路径(ShortestPath)
  2. 第一个顶点为源点(Source)
  3. 最后一个顶点为终点(Destination)

问题分类

  1. 单源最短路问题:

    1. 从某固定源点出发,求其到所有其他顶点的最短路径
    2. (有向)无权图
    3. (无向)有权图
  2. 多源最短路径问题:

    1. 求任意两顶点间的最短路径

7.1.2 无权图的单源最短路

  1. 按照递增(非递减)的顺序找出到各个顶点的最短路
  2. image-20220801185718394
  3. 这是一圈一圈向外扫描的(BFS广度优先搜索),同时也就解决了James Bond从孤岛跳上岸,最少需要多少步

image-20220801190113983

上图中if中判断的条件里的是BFS的,在这里是不需要的,这里需要的是:

dist[W] = SW的最短距离//无穷大、无穷小、-1都可以。因为这些数可以一看到就知道还未被访问过,下面采用-1的方式
dist[S] = 0//初始值是0,表示他到他自己的距离
path[W] = SW的路上经过的某顶点//记录路径,对每一个顶点W,把源点到w的路上一定要经过的某一个顶点存在这个path里面 

image-20220801190047751

单源最短函数算法

void Unweighted ( Vertex S )//unweighted是无权的意思
{
    Enqueue(S,Q);
    while(!IsEmpty(Q)){
        V = Dequeue(Q);//每次弹出来一个顶点,就意味着这个顶点到s的最短路径已经被找到了
        for ( V 的每一个邻接点 W )
            if( dist[W] == -1 ){//正常的数都是正数,-1是属于不会被访问过的
                dist[W] == dist[V]+1;//这个时候W的最短距离就找到了
                path[W] = V//谁是S到W路上必经的顶点呢?那就是他的前一个顶点(V是顶点的编号)。记录下来这个的作用是:顺着path这个数组一个一个往前推,直到推到源点得到一个反向的路径(然后将其压到堆栈里面(堆栈起反序作用,后序先出),从而得到正确的路径)
                Enqueue(W,Q);
            }
    }
}

如果有|V|个顶点和|E|条边的图用邻接表存储,则算法的时间复杂度是多少?

T = O(|V|+|E|)

7.2.2-s 无权图的单源最短路示例

image-20220801223448836

void Unweighted ( Vertex S )//unweighted是无权的意思
{
    Enqueue(S,Q);
    while(!IsEmpty(Q)){//这是判断他是不是为空再决定要不要进行下去
        V = Dequeue(Q);
        for ( V 的每一个邻接点 W )
            if( dist[W] == -1 ){//正常的数都是正数,-1是属于不会被访问过的
                dist[W] == dist[V]+1;
                path[W] = V
                Enqueue(W,Q);
            }
    }
}
​
//dist是点到源点的最短距离
//path是指当前点在那条路径上
//所以所有的信息就都可以从表格中得到