举例:
对一有向图如下图所示:
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; }