Dijkstra算法思想:
设由两个顶点集合S和集合T,集合S中存放图中已找到最短路劲的顶点,集合T存放图中剩余顶点。初始状态时,集合S中只包含愿点,然后不断从集合T中选取到顶点v0路径长度最短的顶点Vu,并并入到集合S中。集合S每并入一个新的顶点Vu,都要修改顶点V0,都要修改顶点V0到集合T中顶点的最短路径长度值。不断重复次过程。
引入3个辅助数组dist[],path[],set[]。
dist[vi]表示当前已找到的从V0到每个终点Vi的最短路径长度。初态为:若从V0到Vi有边,则dist[vi]为边上的权值,否则置dist[vi]为无穷。
path[vi]中保存从V0到vi最短路径上vi的前一个顶点,假设最短路径上的顶点序列为v0,v1,v2。。。。,这path[vi=Vi-1;path[]的初态为:如果V0到Vi有边,则path[Vi]=V0;否则path[Vi]=-1;
set[]为标记数组,set[Vi]=0表示Vi在T中。代码如下:
#ifndef MGRAPH_H_
#define MGRAPH_H_
#define INF 9999
#define maxSize 30
typedef int VertexType;
typedef struct
{
int edges[maxSize][maxSize];
int n,e;
VertexType vex[maxSize];
}MGraph;
void CreateMGraph( MGraph * G)
{
int i,j,k,weight;
int n1,n2;
printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
scanf("%d,%d",&(G->n),&(G->e));
//给顶点编号
for(i=0;i<G->n;i++)
G->vex[i]=i;
for(i=0;i<G->n;i++)
for(j=0;j<G->n;j++)
{
if(i==j)
G->edges[i][j]=0;
else
G->edges[i][j]=INF;
}
printf("请输入对应的边的结点号和边的权值(i,j,w)\n");
for(k=0;k<G->e;k++)
{
printf("第%d条边的结点号和权值:",k+1);
scanf("%d,%d,%d",&i,&j,&weight);
G->edges[i][j]=weight;
}
}
#endif
头文件结束
#include<stdio.h>
#include"MGraph.h"
static int path[maxSize];
void Dijkstra(MGraph g,int v,int dist[],int path[])
{
int set[maxSize];
int min,i,j,u;
//初始化
for(i=0;i<g.n;i++)
{
dist[i]=g.edges[v][i];
set[i]=0;
if(g.edges[v][i]<INF)
path[i]=v;
else
path[i]=-1;
}
set[v]=1;
path[v]=-1;
//关键操作开始
for(i=0;i<g.n;i++)
{
min=INF;
/*这个循环每次从剩余顶点中选出一个顶点,通往这个顶点的路径在通往剩余顶点的路径中是长度最短的*/
for(j=0;j<g.n;j++)
if(set[j]==0&&dist[j]<min)
{
u=j;
min=dist[j];
}
set[u]=1;//将选出的顶点并入最短路径中
/*在这个循环中,以刚并入的顶点作为中间顶点,对所有的剩余顶点路劲进行检测,更新*/
for(j=0;j<g.n;j++)
{
if(set[j]==0&&dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
path[j]=u;
}
}
}
/*********************************关键操作结束*******************************/
}
void PrintfPath(int path[],int a)
{
int stack[maxSize],top=-1;
while(path[a]!=-1)
{
stack[++top]=a;
a=path[a];
}
stack[++top]=a;
printf("最短路径为:\n");
while(top!=-1)
printf("%d,",stack[top--]);
}
void main(void)
{
MGraph g;
int i;
int dist[maxSize];
CreateMGraph(&g);
Dijkstra(g,0,dist,path);
PrintfPath(path,3);
for(i=0;i<g.n;i++)
printf("%d ",dist[i]);
}