举例:
对一有向图如下图所示:
data.txt数据如下:
7 12 顶点和边数
0 1 2 3 4 5 6 顶点name
0 1 2 顶点与顶点之间的权值
0 3 1
1 3 3
1 4 10
2 0 4
2 5 5
3 2 2
3 4 2
3 5 8
3 6 4
4 6 6
6 5 1
代码如下:
// Dijkstra.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#define MAX_VERTEX_NUM 20
#define MAX_VALUE_TYPE INT_MAX
typedef int VertexType;
int visit[MAX_VERTEX_NUM];
typedef struct node
{
VertexType adjvex;
int weight;
struct node* next;
}EdgeNode; //边表节点
typedef struct vnode
{
VertexType vertex;
int dist;
int len;
int path[MAX_VERTEX_NUM];
EdgeNode *firstedge;
}VertexNode; //表头节点
typedef VertexNode adjList[MAX_VERTEX_NUM];
typedef struct
{
adjList adjlist;
int n, e;
}ALGraph;
void CreateALGraph(ALGraph *G)
{
int i, j;
int k;
EdgeNode *s;
scanf("%d%d", &G->n, &G->e);
for (i = 0; i <G->n; i++)
{
scanf("%d", &G->adjlist[i].vertex);
G->adjlist[i].firstedge = NULL;//边表设置成空表
}
for (k = 1; k <= G->e; k++)
{
int nwight = 0;
scanf("%d%d", &i, &j);//i = Locate(G, i); j = Locate(G, j); //查找结点序号
s = (EdgeNode *)malloc(sizeof(EdgeNode));
scanf("%d", &nwight);
s->weight = nwight;
s->adjvex = j;//邻接点序号为j
s->next = G->adjlist[i].firstedge;
G->adjlist[i].firstedge = s;
s = (EdgeNode *)malloc(sizeof(EdgeNode));
s->adjvex = i;
s->weight = nwight;
s->next = G->adjlist[j].firstedge;
G->adjlist[j].firstedge = s;
}
}
void print(ALGraph *G)
{
EdgeNode *p;
int i;
for(i=0; i<G->n; i++)
{
printf("index %d VERTEX %d", i, G->adjlist[i].vertex);
for(p = G->adjlist[i].firstedge; p ; p = p->next)
{
printf("->\tVERTEX %d weight %d", p->adjvex, p->weight);
}
putchar('\n');
}
}
void GetNewPathWay( ALGraph * g , int k , int i )///---------更新路径函数-------------------------
{
int j;
for( j = 0 ; j <= g->adjlist[k].len ; j++ )
g->adjlist[i].path[j] = g->adjlist[k].path[j]; //拷贝k中的路径
g->adjlist[i].path[j] = i;
}
void ShowPathWay( ALGraph * g , int y )///----------------------输出路径函数-------------------------
{
/*int i , j;
for( i = 0 ; i <= g->adjlist[y].len ; i++)
{
if( g->adjlist[y].path[i] != y )
{
printf("最短路径是:\n");
for( j = 0 ; j < i ; j ++)
{
printf("%s->",g->adjlist[g->adjlist[y].path[j]].vertex);
}
printf("%s\n\n",g->adjlist[g->adjlist[y].path[j]].vertex );
printf("最短距离为:\n");
printf("%d\n\n",g->adjlist[y].dist);
}
}
printf("\nERROR:\n");
printf("没有通路\n\n"); */
int i,j;
printf("最短路径是:\n");
for ( i = 0; i <= g->adjlist[y].len; i++)
{
printf("%d->",g->adjlist[g->adjlist[y].path[i]].vertex + 1);
}
printf("\n最短距离为:\n");
printf("%d\n\n",g->adjlist[y].dist);
}
void Visit( ALGraph * g )///-------------初始化路径
{
int i,j;
for( i = 0 ; i <g->n ; i ++)
{
visit[i] = false;
g->adjlist[i].dist = INT_MAX;
g->adjlist[i].len = 0;
for( j = 0 ; j < g->n ; j ++ )
g->adjlist[i].path[j] = INT_MAX;
}
}
void Dijkstra( ALGraph * g )///---------------------DIJKSTRA算法---(权值无负数)---------------------------
{
printf("请输入 开始点 和 结束点:\n");
int x ,y;
while( (scanf("%d",&x))!= EOF , x != -1 && x != 0 && x <= g->n )
{
Visit( g ); //初始化路径
int i , j , k , m , min = 0 , t;
g->adjlist[x-1].dist = 0;
g->adjlist[x-1].path[0] = x-1;
k = x-1;
EdgeNode * p;
for( i = 0 ; i < g->n ; i ++)//计算每个点到其实点的距离
{
t = INT_MAX;
p = g->adjlist[k].firstedge;
visit[k] = true; //k表示已经访问了
while( p )
{
if( !visit[p->adjvex])//如果这个节点没有访问过
{
if( g->adjlist[k].dist == INT_MAX )
{
g->adjlist[p->adjvex].dist = p->weight;
g->adjlist[p->adjvex].len = g->adjlist[k].len+1;
GetNewPathWay( g , k , p->adjvex);
}
else if( g->adjlist[k].dist + p->weight < g->adjlist[p->adjvex].dist )
{
g->adjlist[p->adjvex].dist = g->adjlist[k].dist + p->weight;
g->adjlist[p->adjvex].len = g->adjlist[k].len+1;
GetNewPathWay( g ,k , p->adjvex);
}
}
p = p->next;
}
for( j = 0 ; j < g->n ; j++)
{
if( g->adjlist[j].dist < t && !visit[j] )
{
t = g->adjlist[j].dist;
min = j;
}
}
k = min;
}
while(scanf("%d",&y)!=EOF , y != -1 && y != 0 && y <= g->n )
{
ShowPathWay( g ,y-1 );
printf("请输入%d--> 的下一个顶点(-1结束): \n",x );
break;
}
printf("请输入 开始点 和结束点 (-1结束):\n");
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
FILE *fp;
fp = freopen("my.txt", "r", stdin);
ALGraph G;
CreateALGraph(&G);
/*fclose(fp);*/
print(&G);
Dijkstra(&G);
return 0;
}