Dijkstra算法

带权图分为有向和无向,无向图的有求最小生成树的prime算法和kruskal算法,链接:https://blog.csdn.net/qq_35247337/article/details/107319361

有向图的最短路径算法有dijkstra算法和floyd算法。这里记录dijkstra算法。

------------------

Dijkstra 算法找到了从任意指定顶点到任何其他顶点的最短路径,而且证实可以到达图中的所有其他顶点。它使用了通常被称为贪心的策略或算法。贪心算法把问题分解成小块或步骤,并且在每一步中确定最优解,用这些最优解合并生成最终的解。

Dijkstra 算法的思想就是首先把起点到所有点的距离存下来找个最短的,之后把这个距离最短的点作为中转站再来遍历一遍更新所有点的距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。

具体的过程详解我推荐一篇文章,写的蛮仔细的:https://www.cnblogs.com/jason2003/p/7222182.html

这里写一下C#实现的代码:

//记录原始顶点与远距离顶点之间的关系
public class DistOriginal
{
    public int distance;
    public int parentVert;
    public DistOriginal(int pv, int d)
    {
        distance = d;
        parentVert = pv;
    }
}

public class Vertex
{
    public string label;
    public bool isInTree;
    public Vertex(string lab)
    {
        label = lab;
        isInTree = false;
    }
}

public class Graph
{
    private const int max_verts = 20;
    int infinity = 1000000;
    Vertex[] vertexList;//所有顶点集合
    int[,] adjMat;//邻接矩阵
    int nVerts;//当前拥有的顶点数量
    int nTree;//当前树中拥有的顶点数量
    DistOriginal[] sPath;
    int currentVert;
    int startToCurrent;

    public Graph()
    {
        vertexList = new Vertex[max_verts];
        adjMat = new int[max_verts, max_verts];
        nVerts = 0;
        nTree = 0;
        for (int j = 0; j <= max_verts - 1; j++)
            for (int k = 0; k <= max_verts - 1; k++)
                adjMat[j, k] = infinity;

        sPath = new DistOriginal[max_verts];
    }

    public void AddVertex(string lab)
    {
        vertexList[nVerts] = new Vertex(lab);
        nVerts++;
    }

    public void AddEdge(int start, int theEnd, int weight)
    {
        adjMat[start, theEnd] = weight;
    }

    public void Path()
    {
        int startTree = 0;
        vertexList[startTree].isInTree = true;
        nTree = 1;

        for (int j = 0; j <= nVerts; j++)
        {
            int tempDist = adjMat[startTree, j];
            sPath[j] = new DistOriginal(startTree, tempDist);
        }

        while (nTree < nVerts)
        {
            int indexMin = GetMin();
            int minDist = sPath[indexMin].distance;
            currentVert = indexMin;
            startToCurrent = sPath[indexMin].distance;
            vertexList[currentVert].isInTree = true;
            nTree++;
            AdjustShortPath();
        }

        DisplayPaths();
        nTree = 0;
        for (int j = 0; j <= nVerts - 1; j++)
            vertexList[j].isInTree = false;
   }

    public int GetMin()
    {
        int minDist = infinity;
        int indexMin = 0;
        for (int j = 1; j <= nVerts - 1; j++)
        {
            if (!(vertexList[j].isInTree) && sPath[j].distance < minDist)
            {
                minDist = sPath[j].distance;
                indexMin = j;
            }
        }
            
        return indexMin;
    }

    public void AdjustShortPath()
    {
        int column = 1;
        while (column < nVerts)
        if (vertexList[column].isInTree)
            column++;
        else
        {
            int currentToFring = adjMat[currentVert, column];
            int startToFringe = startToCurrent + currentToFring;
            int sPathDist = sPath[column].distance;
            if (startToFringe < sPathDist)
            {
                sPath[column].parentVert = currentVert;
                sPath[column].distance = startToFringe;
            }
            column++;
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值