c#Dijkstra(狄克斯特拉)算法实现

Dijkstra


Dijkstra算法概念

笔者认为Dijkstra 其算法本质广度优先搜索(BFS)。其算法思想为设置两个集合S和T,集合S中存放已找到的最短路径的节点,集合T中存放尚未找到的最短路径的节点。初始状态下,S中只包含源点,然后从集合T中遍历找到源点路径长度(权值)最小的节点U加入到集合S中,T中去除该节点。集合S中每加入一个节点,集合T中各节点的新的最短路径为原来的路径长度与现在从源点经过当前节点到达T中各节点新的最短路径长度的较小值。此过程重复,直至T中所有节点到S中。
图中的权值不能为负数。

实现

 
这里写图片描述
由图生成的二维数组为 
其中Max代表两点之间不能连通

0123456
07Max2Max20Max
7034MaxMaxMax
Max3023MaxMax
242076Max
MaxMax37043
20MaxMax6401
MaxMaxMaxMax310

算法步骤 
1、源点为0,S中含有节点0,T中含有剩余节点。源点到其他节点的路径为:

0(已用)123456
07Max2Max20Max

2、源点到节点3的路径最短,故S中放入节点3,节点3标志为已用,此时源点经过节点3到其他节点的最短路径为:

0(已用)123(已用)456
064298Max

3、T中最短路径节点为2,将节点2放入S中,此时源点经过节点2到其他节点的最短路径为:

0(已用)12(已用)3(已用)456
064278Max

4、T中最短路径节点为1,将节点1放入S中,此时源点经过节点1到其他节点的最短路径为:

0(已用)1(已用)2(已用)3(已用)456
064278Max

5、T中最短路径节点为4,将节点4放入S中,此时源点经过节点4到其他节点的最短路径为:

0(已用)1(已用)2(已用)3(已用)4(已用)56
06427810

6、T中最短路径节点为5,将节点5放入S中,此时源点经过节点5到其他节点的最短路为:

0(已用)1(已用)2(已用)3(已用)4(已用)5(已用)6
0642789

7、T中最短路径节点为6,将节点6放入S中,此时源点经过节点6到其他节点的最短路为:

0(已用)1(已用)2(已用)3(已用)4(已用)5(已用)6(已用)
0642789

最后由节点0到节点6的最短路径长度为9,路径为0-3-5-6.

代码实现 

    static void Dijkstra(int[,] mgrap, int v)
        {
            int len = mgrap.GetLength(0);//节点个数
            int[] dist = new int[len];//从原点v到其他的各定点当前的最短路径长度
            int[] path = new int[len];//path[i]表示从原点到定点i之间最短路径的前驱节点
            int[] s = new int[len];   //选定的顶点的集合
            int mindis, i, j, u;
            u = 0;
            for (i = 0; i < len; i++)
            {
                dist[i] = mgrap[v, i];       //距离初始化
                s[i] = 0;                        //s[]置空  0表示i不在s集合中
                if (mgrap[v, i] < int.MaxValue)        //路径初始化
                    path[i] = v;
                else
                    path[i] = -1;
            }
            s[v] = 1;                  //源点编号v放入s中
            path[v] = 0;
            for (i = 0; i < len; i++)                //循环直到所有顶点的最短路径都求出
            {
                mindis = int.MaxValue;                    //mindis置最小长度初值
                for (j = 0; j < len; j++)         //选取不在s中且具有最小距离的顶点u
                    if (s[j] == 0 && dist[j] < mindis)
                    {
                        u = j;
                        mindis = dist[j];
                    }
                s[u] = 1;                       //顶点u加入s中
                for (j = 0; j < len; j++)         //修改不在s中的顶点的距离
                    if (s[j] == 0)
                        if (mgrap[u, j] < int.MaxValue && dist[u] + mgrap[u, j] < dist[j])
                        {
                            dist[j] = dist[u] + mgrap[u, j];
                            path[j] = u;
                        }
            }

        }
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
狄克斯特拉算法Dijkstra's algorithm)是一种解决单源最短路径问题的贪心算法。下面是一个用C语言实现狄克斯特拉算法的示例代码: ```c #include <stdio.h> #include <limits.h> #define V 9 // 图中顶点的数量 // 找到距离数组dist[]中最小距离的顶点的索引 int minDistance(int dist[], int visited[]) { int min = INT_MAX, min_index; for (int v = 0; v < V; v++) { if (!visited[v] && dist[v] <= min) { min = dist[v]; min_index = v; } } return min_index; } // 打印结果 void printSolution(int dist[]) { printf("顶点\t距离\n"); for (int i = 0; i < V; i++) { printf("%d\t%d\n", i, dist[i]); } } // 狄克斯特拉算法 void dijkstra(int graph[V][V], int src) { int dist[V], visited[V]; // 初始化距离数组和visited数组 for (int i = 0; i < V; i++) { dist[i] = INT_MAX; visited[i] = 0; } dist[src] = 0; // 找到最短路径 for (int count = 0; count < V - 1; count++) { int u = minDistance(dist, visited); visited[u] = 1; for (int v = 0; v < V; v++) { if (!visited[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; } } } // 打印最短路径 printSolution(dist); } // 测试 int main() { int graph[V][V] = {{0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0}}; dijkstra(graph, 0); return 0; } ``` 在这个示例代码中,我们使用邻接矩阵表示图。我们首先将距离数组和visited数组初始化。然后在循环中找到最短路径,并更新距离数组。最后,我们打印最短路径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值