main.c
#include <stdio.h>
#include "graph.h"
extern int dist[MAXN];
extern char path[MAXN][MAXN];
int main()
{
struct graph * g = create();
//printfGraph( g);
//DFS_S(g);
dijkstra(g,1);
int i;
for(i=0;i<g->n;i++)
{
if(i != 1)
printf("%c->%c的最短路径为%s,最短路径为%d\n",g->V[1],g->V[i],path[i],dist[i]);
}
return 0;
}
graph.h
#ifndef __GRAPH_H__
#define __GRAPH_H__
#define MAX_NUMBER 100000000
typedef char Vtype;//定义顶点类型
typedef int Atype;//权值类型
#define MAXN 100 //表示顶点个数最多为MAXN
struct graph
{
Vtype V[MAXN];
Atype A[MAXN][MAXN];
int n;//记录顶点的个数
//按需增加
};
typedef struct graph Graph;
//邻接矩阵法创建图
struct graph * create();
void printfGraph(struct graph * g);
//从顶点数组中找到 顶点 c 的下标
int getIndex(struct graph * g,char c);
//依次从图的各个顶点出发,进行深度优先搜索
void DFS_S(struct graph * g);
void dijkstra(struct graph * g,int m);
#endif
graph.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graph.h"
int flag[MAXN] = {0};
//flag[i] = 0;//代表vi没有被访问
//flag[i] = 1;//代表vi被访问了
int dist[MAXN];
int S[MAXN];
char path[MAXN][MAXN];
//char *path[MAXN];
struct graph * create()
{
struct graph * g = (struct graph *)malloc(sizeof(struct graph));
int i,j;
for(i=0;i<MAXN;i++)
{
for(j=0;j<MAXN;j++)
{
g->A[i][j] = MAX_NUMBER;
}
}
printf("请输入顶点:");//abcdef
scanf("%s",g->V);
getchar();
g->n = strlen(g->V);
printf("顶点有:%s\n",g->V);
printf("顶点个数为:%d\n",g->n);
printf("请输入顶点之间的关系:");//约定以顶点权值顶点的格式输入,比如: A5B
//以 #0# 结束输入
char s,p;
int w;
while(1)
{
scanf("%c%d%c",&s,&w,&p);
//printf("边间关系:%c%d%c\n",s,w,p);
getchar();//消耗回车
if(s=='#' && w == 0 && p=='#')
break;
int i = getIndex(g,s);
int j = getIndex(g,p);
if(i==-1 || j==-1)
{
printf("您输入有误,请重新输入\n");
continue;
}
g->A[i][j] = w;
}
return g;
}
void printfGraph(struct graph * g)
{
int i,j;
for(i=0;i<g->n;i++)
{
for(j=0;j<g->n;j++)
{
if(g->A[i][j] != MAX_NUMBER)
printf("%d ",g->A[i][j]);
else
printf("# ");
}
printf("\n");
}
}
//从顶点数组中找到 顶点 c 的下标
int getIndex(struct graph * g,char c)
{
int i;
for(i=0;i<g->n;i++)
{
if(g->V[i] == c)
{
return i;
}
}
return -1;
}
/*
获取图g中 vi的第j个邻接点
*/
int getC(struct graph * g,int i,int j)
{
//只需要对 g->A数组的第i行进行判断即可
int x;
int count = 0;
for(x=0;x<g->n;x++)
{
if(g->A[i][x] != MAX_NUMBER)//vx是vi的邻接点
{
count++;
if(count == j)//vx是vi的第j个邻接点
{
return x;
}
}
}
return -1;//没有找到第j个邻接点,就返回不存在的下标 -1
}
/*
深度优先搜索
参数
g:图的头结点地址
i:图的顶点下标
*/
void DFS(struct graph * g,int i)
{
//访问 vi,并且把flag数组置1
printf("%c ",g->V[i]);
flag[i] = 1;
//依次从vi的各个邻接点vu出发,对vu进行深度优先搜索
int u;
int y;
for(u=1;(y=getC(g,i,u))!=-1;u++)
{
//y = getC(g, i ,u);
if(flag[y] == 0)//未被访问,就以深度优先搜索的方法访问它
{
DFS(g,y);
}
}
}
//依次从图的各个顶点出发,进行深度优先搜索
void DFS_S(struct graph * g)
{
int i;
for(i=0;i<g->n;i++)
{
if(flag[i] == 0)//未被访问
{
DFS(g,i);
}
}
}
void dijkstra(struct graph * g,int m)
{
//初始化三个辅助数组
int i;
for(i=0;i<g->n;i++)
{
dist[i] = g->A[m][i];//初始距离设置为“直接距离”
S[i] = 0;
memset(path[i],'\0',MAXN);
path[i][0] = g->V[m];
path[i][1] = g->V[i];
}
S[m] = 1;//不考虑自己到自己的路径
int n = 0;
while(n++ < g->n)
{
//1,找出dist数组中最小的值(除去已经被确定了的)
int min_dist = dist[0];
int u = 0;//最小的dist的下标
for(i=0;i<g->n;i++)
{
if(S[i]==0)
{
if(dist[i]<min_dist)
{
min_dist = dist[i];
u = i;
}
}
}
//dist[u] 就是我们要找的
S[u] = 1;//顶点下标为u的最短路径已经被确定了
//2,用 vu 作为中间顶点来更新其他的
for(i=0;i<g->n;i++)
{
if(S[i]==0)
{
if(dist[u]+g->A[u][i] < dist[i])
{
dist[i] = dist[u]+g->A[u][i];//更新最短距离
//还需要更新路径 path[i]
//把 path[u]+vi
strcpy(path[i],path[u]);
path[i][strlen(path[i])] = g->V[i];
}
}
}
}
}