图-迪杰斯特拉(dijkstra)算法

  • 迪杰斯特拉算法:是一种典型的最短路径算法,用于计算一个结点到其他结点的最短路径,主要特点是以起始点为中心向外层层扩展(广度优先思想),直到扩展到终点。
    算法思想:找到离源点最近的一个点,找到以该点为中心,找到源点到其他节点的最短路径。
    举例详细分析
    这里写图片描述
    采用邻接矩阵存储图,顶点之间不可达记为无穷大,上图对角线也是无穷大。
    计算顶点1的最短路径
    1.首先定义一个dis数组,将1到其他顶点的的距离保存到数组里。
    这里写图片描述
    2.定义一个book数组,标记dis数组中的顶点是否被处理过。
    3.在dis中寻找离源点距离最近的2号点,以2号点为源点,并将2号点标记,根据2号点到可达顶点的距离优化dis数组的距离。
    2->3 :9 2->4 :3
    1->2->:1+9 = 10 < 12更新,1->2->4:1+3=4 < 无穷大 更新
    更新后的dis数组
    这里写图片描述
    4.在3和4中选择距离较小的4作为源点优化dis数组,将结点4标记
    4->3 :4 4->5:13 4->6:15
    1->4->3:4+4 = 8>10更新1->4->5:4+13=17 < 无穷大 更新
    1->4->6:4+15 = 19 < 无穷大 更新
    更新后的dis数组
    这里写图片描述
    5.dis中选择没有被标记且距离最短的顶点,3,以3为顶点优化dis数组并将3标记。
    3->5:5
    1->3->5:8+5=13<17更新,更新后的dis
    这里写图片描述
    6.继续从dis中选择没有访问且距离最短的点5,并将5标记,以5为源点优化dis数组。
    5->6 :4,
    1->5->6:13+7 = 17 < 19优化
    优化后的dis
    这里写图片描述
    7.继续从dis中选择没有访问且距离最短的点6,并将6标记,以6为源点优化dis数组,发现6没有可达顶点此时dis数组中的所有点都经过处理了最终的dis为
    这里写图片描述
    也就是源点1到各个顶点的最短路径,整个过程我们已经掌握了下面我们来完成代码
//dijkstra算法求最短顶点的最短路径
    vector<int> Dijkstra(const V& des)
    {
        //定义dis数组保存源点到其他节点的初始路径
        vector<int> dis(_vertex.size(),0);
        //将所有的顶点分为两个部分,已知最短路径的顶点集合P和未知的顶点集合Q,
        //初始时,P中只有一个源顶点1号。
        //这里用book数组来标记顶点是否在P中,1表示在P中,0表示在Q中。
        vector <int> book(_vertex.size(),0);
        int index = GetIndexofVertex(des);
        book[index] = 1;
        //初始化dis
        for (size_t i = 0; i < _edge.size(); i++)
        {
            dis[i] = _edge[index][i];//存储源点到其他顶点的初始距离
        }
        while (true)
        {
            //寻找离源点距离最近且未被处理过的顶点下标
            int idx = -1;
            int min = INT_MAX;
            for (size_t j = 0; j < dis.size(); j++)
            {
                if (book[j] == 0 && dis[j] < min)//没有被处理且可达距离最小
                {
                    idx = j;
                    min = dis[j];
                }
            }
            if (idx == -1)//没有找到未处理的点//已经处理完
                break;
            book[idx] = 1;
            //更新源点到各个结点的最短路径
            for (size_t k = 0; k < dis.size(); k++)
            {
                if (_edge[idx][k] < INT_MAX)//可达
                {
                    //源点到该节点的距离比通过下标为idx的结点到该节点的距离大就更新
                    if (dis[k] > dis[idx] + _edge[idx][k])
                    {
                        dis[k] = dis[idx] + _edge[idx][k];
                    }
                }
            }

        }
        return dis;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值