• 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("请输入图中顶点的数目和边的数目,中间用逗号隔开:
    ");
        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 :
    ");
            scanf("%d,%d,%d",&i,&j,&w);
            G->edge[i][j] = w;
            G->edge[j][i] = G->edge[i][j];
        }
        printf("
    ");
        for(i = 0;i < G->numvex;i++)
        {
            for(j = 0;j < G->numvex;j++)
            {
              printf("%d  ",G->edge[i][j]);
            }
            printf("
    ");
        }
    }
    
    //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*的最短路径为:
    ");
        ShortestPathByDijkstra(&G,k,&P,&D);
        return 0;
    }
    

      

  • 相关阅读:
    button 垂直分布
    GitHub上值得关注的iOS开源项目
    电脑连接网络(网络正常),但不能上网,登录网页提示dns_probe_finished_no_internet
    android 模拟应用因内存不足被后台杀死命令
    android 屏幕划分
    android 没有root的手机导出数据库
    移动硬盘不能识别,设备管理器中显示黄色感叹号
    低功耗蓝牙开发(BLE)
    音视频学习笔记
    Java中为什么要使用线程池?如何使用?
  • 原文地址:https://www.cnblogs.com/devinblog/p/4179890.html
Copyright © 2020-2023  润新知