Dijkstra算法(迪杰斯塔拉算法)

本文详细介绍了Dijkstra算法的基本原理及其实现过程。该算法是一种典型的最短路径算法,用于计算图中一个节点到其他所有节点的最短路径。文章通过逐步讲解算法思想,并给出具体的C语言实现代码,帮助读者理解如何利用Dijkstra算法解决实际问题。

算法描述:  

  Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

  Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。

其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#define MAXVERTEX 20
#define INF 65535
typedef char VertexType;
typedef int EdgeType;
typedef int Pathmatirx[MAXVERTEX];
typedef int ShortPathTable[MAXVERTEX];
typedef struct MGraph
{
    VertexType vertex[MAXVERTEX];
    EdgeType edge[MAXVERTEX][MAXVERTEX];
    int numvex;
    int numedge;
}MGraph;

void CreateMGraph(MGraph *G)
{
    int i = 0,j = 0,k = 0,w = 0;
    printf("请输入图中顶点的数目和边的数目,中间用逗号隔开:\n");
    scanf("%d,%d",&G->numvex,&G->numedge);
    for(i = 0;i < G->numvex;i++)
    {
        for(j = 0;j < G->numvex;j++)
        {
            if(i == j)
            {
                G->edge[i][j] = 0;
            }
            else
            {
                G->edge[i][j] = INF;
            }
        }
    }
    for(k = 0;k < G->numedge;k++)
    {
        printf("请输入边vi-vj的边的下标 i 和 j ,以及权重w :\n");
        scanf("%d,%d,%d",&i,&j,&w);
        G->edge[i][j] = w;
        G->edge[j][i] = G->edge[i][j];
    }
    printf("\n");
    for(i = 0;i < G->numvex;i++)
    {
        for(j = 0;j < G->numvex;j++)
        {
          printf("%d  ",G->edge[i][j]);
        }
        printf("\n");
    }
}

//Dijkstra算法实现

void ShortestPathByDijkstra(MGraph *G,int v0,Pathmatirx *P,ShortPathTable *D)
{
    int i,j,k,w,min;
    int final[MAXVERTEX];

    for(i = 0;i < G->numvex;i++)
    {
        final[i] = 0;
        (*D)[i] = G->edge[v0][i];
        (*P)[i] = 0;
    }
    final[v0] = 1;
    (*D)[v0] = 0;
    for(i = 1;i <G->numvex;i++)
    {
        min = INF;
        for(j = 0;j < G->numvex; j++)
        {
            if(final[j] == 0 && min > (*D)[j])
            {
                min = (*D)[j];
                k = j;
            }
        }

        final[k] = 1;
        for(w = 0;w < G->numvex;w++)
        {
            if(final[w] == 0 &&(min + G->edge[k][w] < (*D)[w]))
            {
                (*D)[w] = min + G->edge[k][w];
                (*P)[w] = k;
            }
        }
    }
    for(i = 0;i < G->numvex;i++)
    {
        printf("%d",(*P)[i]);
    }
}

int main()
{
    int k = 0;
    struct MGraph G;
    Pathmatirx P;
    ShortPathTable D;
    CreateMGraph(&G);
    printf("Dijkstra算法求得的V0到V*的最短路径为:\n");
    ShortestPathByDijkstra(&G,k,&P,&D);
    return 0;
}

  

posted on 2014-12-23 13:05 BeatificDevin 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/devinblog/p/4179890.html

### Dijkstra算法的核心概念 Dijkstra算法是一种用于计算加权图中单源最短路径的经典贪心算法[^1]。它通过逐步扩展已知距离最小的节点来构建全局最优解,适用于边权重为非负数的情况。 #### 算法基本原理 该算法基于这样一个事实:如果已经找到了某个顶点到起点的距离是最短的,则可以通过这个顶点更新其他相邻顶点的距离。具体来说,对于每一个未访问过的顶点,记录其当前所知道的从起始顶点出发到达它的最短路径长度;每次从未处理集合中选取具有最小临时标记值的一个作为新的永久标记,并以此为基础进一步探索其余可能更优的选择直到完成整个过程为止。 以下是Python中的简单实现: ```python import heapq def dijkstra(graph, start): distances = {node: float('infinity') for node in graph} distances[start] = 0 priority_queue = [(0, start)] while priority_queue: current_distance, current_node = heapq.heappop(priority_queue) if current_distance > distances[current_node]: continue for neighbor, weight in graph[current_node].items(): distance = current_distance + weight if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(priority_queue, (distance, neighbor)) return distances ``` 此代码片段定义了一个`dijkstra`函数接收两个参数——表示邻接表形式存储的图形结构 `graph` 和初始结点名称字符串类型的变量 `start`. 它返回字典对象其中键代表各个目标位置而对应的数值则指示它们各自离原点最近的具体里程数. #### 应用场景举例 - **网络路由协议**: OSPF(开放式最短路径优先)就是利用了类似的机制来进行数据包转发决策. - **地图服务提供商**: 如Google Maps 使用此类技术帮助用户找到两点间最快的行车路线. 尽管如此强大,Dijkstra并不支持含有负权重边的地图因为这可能导致无限循环或者错误的结果生成.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值