单源最短路径:Dijkstra算法

单源最短路径:Dijkstra算法

预定义

#include 
#define MAX_SIZE 20     //最大顶点数
#define MAX_WEIGHT 8888 //最大权值
typedef int VType;
typedef int WType;

有向网

/*图结构体*/
typedef struct Graph
{
     
    VType vertex[MAX_SIZE];   //顶点数组
    int vernum;     //顶点个数
    WType arc[MAX_SIZE][MAX_SIZE];  //弧矩阵
    int arcnum;     //弧个数
}MGraph;

/*定位顶点值在顶点数组中的次序*/
int locateVertex(MGraph G, VType v)
{
     
    for(int i=0; i<G.arcnum; ++i)
        if(G.vertex[i] == v)
            return i;
    return -1;
}

/*创爱有向网*/
void CreateDN(MGraph *G)
{
     
    printf("请输入有向网的顶点数 弧数:");
    scanf("%d %d", &G->vernum, &G->arcnum);
    /*构建顶点数组*/
    printf("请输入顶点值:");
    for(int i=0; i<G->vernum; ++i)
        scanf("%d", &G->vertex[i]);
    /*初始化弧矩阵*/
    for(int i=0; i<G->vernum; ++i)
        for(int j=0; j<G->vernum; ++j)
            G->arc[i][j]=MAX_WEIGHT;
    /*构建弧矩阵*/
    int b, e;
    VType v1, v2;
    WType w;
    printf("请输入弧起点值, 终点值, 权值:\n");
    for(int i=0; i<G->arcnum; ++i)
    {
     
        scanf("%d %d %d", &v1, &v2, &w);
        b = locateVertex(*G, v1);
        e = locateVertex(*G, v2);
        G->arc[b][e] = w;
    }
}

Dijkstra算法

/*ShortestPath_DIJ算法
	v0:起始点
	D[v]:从v0到v的最短路径长度
	p[v][w]:值为真时,表示从v0到v的最短路径经过了顶点w
	Finish[v]:值为真表示从v0到v的最短路径已经找到
*/
void ShortestPath_DIJ(MGraph G, int v0, int P[][MAX_SIZE], WType D[])   //或int (*P)[MAX_SIZE], WType *D
{
     
	/*初始化辅助结构*/
    int Final[MAX_SIZE] = {
     0};      //最短路径标记
	for(int v=0; v<G.vernum; ++v)
    {
     
        Final[v] = 0;           //初始化标记数组
        D[v] = G.arc[v0][v];    //初始化从v0到v的距离数组
        for(int i=0; i<G.vernum; ++i)   //初始化从v0到v经过的顶点i 数组
            P[v][i] = 0;
        if(D[v]<MAX_WEIGHT) {
     P[v][v0]=1; P[v][v]=1; }   //因为v0和v都一定在最短路径上
    }
    D[v0] = 0;
    Final[v0] = 1;
    /*主循环,每次找一个从v0到v的最短路径*/
    for(int i=1; i<G.vernum; ++i)   //还有vernum-1个顶点未求解,循环vernum-1次
    {
     
        int v; //权值最小的顶点
        WType min=MAX_WEIGHT;
        /*从D中找距离最小顶点 v*/
        for(int w=0; w<G.arcnum; ++w)
        {
     
            if(Final[w]!=1 && D[w]<min)
            {
     
                v = w;
                min = D[w];
            }
        }
        Final[v] = 1; //标记顶点v加入路径
        /*遍历顶点v的邻接点,并更新相关信息*/
        for(int w=0; w<G.vernum; ++w)
        {
     
            //当某邻接点未被求解,且从v0到该邻接点的距离更小时
            if(Final[w]!=1 && (min+G.arc[v][w])<D[w])
            {
     
                D[w] = min+G.arc[v][w];  //更新距离
                //P[w]=P[v]+[w]
                for(int i=0; i<G.vernum; ++i)
                    P[w][i] = P[v][i];
                P[w][w] = 1;
            }
        }
    }
}

测试

int main()
{
     
    MGraph G;
    CreateDN(&G);
    int P[MAX_SIZE][MAX_SIZE];
    int D[MAX_SIZE];
    ShortestPath_DIJ(G, 0, P, D);

    printf("\n\nVertex:\n");
    for(int i=0; i<G.vernum; ++i)
        printf("%d ", G.vertex[i]);

    printf("\n\narc:\n");
    for(int i=0; i<G.vernum; ++i)
    {
     
        for(int j=0; j<G.vernum; ++j)
            printf("%d ", G.arc[i][j]);
        printf("\n");
    }

    printf("\n\nD:\n");
    for(int i=0; i<G.vernum; ++i)
        printf("%d ", D[i]);
    printf("\n\nP:\n");
    for(int i=0; i<G.vernum; ++i)
    {
     
        for(int j=0; j<G.vernum; ++j)
            printf("%d ", P[i][j]);
        printf("\n");
    }
	return 0;
 }

你可能感兴趣的:(数据结构,Dijkstra算法,单源最短路径,Dijkstra,数据结构)