Dijkstra算法思想及实现以及输出具体路径

这个和我上一篇随笔差不多,只是不仅要知道给定点到所有其他点的最短路径,而且还要把路径给数出来,思想很好理解,如图:

Dijkstra算法思想及实现以及输出具体路径

顶点1到5的最短路径是14,具体路径是1-->4-->6-->5这个先后顺序是如何确定的?其实很简单,当你用Dijstra算法跑过一遍后,那么D[i]里的值就应该是最新的,也就是给定点到其他所有点的最短路劲长度已经确定了(下标从0开始),D[0]=0,D[1]=5,D[2]=9,D[3]=7,D[4]=14,D[5]=13,所以从这就可以看出D[5]<D[4],所以6在5的前面通过前面求出来的P[i][j]数组可以知道所要经过的点,而有D[i]数组又可以知道前后顺序,及要想输出路径,只要将所经过的点按D[i]的大小排序后再按从小到大的顺序输出即可。说的简单一点,也就是说这条路径上的点到源点的路径是在递增的,这个好理解吧,所以重点就在如何排序

定义一个结构体,用来保存节点到始点的路径长度和在图中的位置

typedef struct		//路径结构体

{

	int index;

	int weight;

}path;

  路径只可能越来越长,所以按weight排序没有相同的元素,用qsort是稳定的,qsort比较函数

int comp(const void *a,const void *b)	//qsort比较函数

{

	return (*(path *)a).weight-(*(path *)b).weight;

}

  关键代码在输出部分

	for (i=0;i<g->vexnum;i++)

	{

		if (i!=v0)

		{

			printf("路径长度为:%d 路径为:",D[i]);

			int k=0,j;

			for (j=0;j<g->vexnum;j++)

			{

				if (P[i][j]==1&&(i!=j))

				{

					path_point[k].index=j;

					path_point[k++].weight=D[j];

				}

			}

			path_point[k].index=i;

			path_point[k++].weight=D[i];

			qsort(path_point,k,sizeof(path),comp);

			for (j=0;j<k;j++)

			{

				if (j==0)

				{

					printf("%c",g->vexs[path_point[j].index]);

				}

				else

				{

					printf("-->%c",g->vexs[path_point[j].index]);

				}				

			}

			printf("\n\n");

		}

	}

  项目的完整代码如下:

/*graph.h*/

//---------图的数组(邻接矩阵)存储表示----------

#include<stdio.h>

#include <string.h>

#include <stdlib.h>

#define INFINITY  10000        //最大值

#define MAX_VERTEX_NUM 20        //最大顶点个数  

typedef int VRType;        

typedef char VertexType;    

typedef char InfoType;       

typedef enum{DG,DN,UDG,UDN}  GraphKind; //有向图,有向网,无向图,无向网

typedef struct ArcCell

{

    VRType adj;                            //顶点关系类型,对无权图,有1或0表示是否相邻;对带权图,则为权值类型。

    InfoType *info;                        //弧相关信息的指针

}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];



typedef struct

{

    VertexType vexs[MAX_VERTEX_NUM];       //顶点向量

    AdjMatrix  arcs;                       //邻接矩阵

    int        vexnum,arcnum;              //图的当前顶点数和弧数

}mgraph,*MGraph;



typedef struct        //路径结构体

{

    int index;

    int weight;

}path;



int comp(const void *a,const void *b)    //qsort比较函数

{

    return (*(path *)a).weight-(*(path *)b).weight;

}



int Locate_vexs(MGraph &g,VertexType v)        //定位顶点位置

{

    for (int i=0;i<g->vexnum;i++)

        if (g->vexs[i]==v)

            return i;

    return -1;

}



void Print_mgraph(MGraph &g)        //打印图

{    

    int i;

    printf("邻接矩阵为:\n");

    printf("");    //五个空格

    for (i=0;i<g->vexnum;i++)

        printf("%c     ",g->vexs[i]);

    printf("\n\n");



    for (i=0;i<g->vexnum;i++)

    {

        printf("%c     ",g->vexs[i]);

        for (int j=0;j<g->vexnum;j++)

        {

            //输出矩阵,并且调整矩阵

            if (g->arcs[i][j].adj>0&&g->arcs[i][j].adj<10)

                printf("%d     ",g->arcs[i][j].adj);

            else if (g->arcs[i][j].adj>9&&g->arcs[i][j].adj<100)

                printf("%d    ",g->arcs[i][j].adj);

            else if (g->arcs[i][j].adj>99&&g->arcs[i][j].adj<1000)

                printf("%d   ",g->arcs[i][j].adj);

            else if (g->arcs[i][j].adj>999&&g->arcs[i][j].adj<10000)

                printf("%d  ",g->arcs[i][j].adj);

            else if(g->arcs[i][j].adj==INFINITY)

                printf("");

        }

        printf("\n\n");

    }    

}



void Add_vexs(MGraph &g)            //增加顶点

{

    printf("请输入顶点个数:");

    scanf("%d",&g->vexnum);

    getchar();                        //吸收回车符

    printf("请输入顶点字符串序列:");

    for (int i=0;i<g->vexnum;i++)

        scanf("%c",&g->vexs[i]);

}



void Add_arcs(MGraph &g)            //增加边

{

    printf("请输入边的条数:");

    scanf("%d",&g->arcnum);

    VertexType v1,v2;

    int row,col;

    VRType weight;

    printf("请输入权重和对应顶点,以空格隔开:\n");

    for (int i=0;i<g->arcnum;i++)

    {

        scanf("%d %c %c",&weight,&v1,&v2);

        row=Locate_vexs(g,v1);

        col=Locate_vexs(g,v2);

        g->arcs[row][col].adj=weight;

        

    }

}



void Init_graph(MGraph &g)            //初始化图

{

    g=(MGraph)malloc(sizeof(mgraph));

    g->vexnum=0;

    g->arcnum=0;

    for (int i=0;i<MAX_VERTEX_NUM;i++)

        g->vexs[i]='0';

    for (i=0;i<MAX_VERTEX_NUM;i++)

        for (int j=0;j<MAX_VERTEX_NUM;j++)

        {

            g->arcs[i][j].adj=INFINITY;

            g->arcs[i][j].info=NULL;

        }

}



void Create_mgraph(MGraph &g)        //创建图

{

    Add_vexs(g);

    Add_arcs(g);

}

代码和上一篇的改动不是太大,所以只给出部分截图:

Dijkstra算法思想及实现以及输出具体路径

你可能感兴趣的:(dijkstra)