一、Dijkstra算法
/*------------Dijkstra算法--------------*/
Vertex FindMinDist(MGraph Graph,int dist[],int collected[])
{
//返回未被收录顶点中的dist最小者
Vertex MinV,V;
int MinDist=INFINITY;
for(V=0;V<Graph->Nv ;V++){
if(collected[V]==false&&dist[V]<MinDist){
//若V未被收录并且权值更小
MinDist=dist[V];//更新权值
MinV=V;//更新对应顶点
}
}
if(MinDist<INFINITY)//找到最小权值
return MinV;//返回对应顶点
else return ERROR;
}
bool Dijkstra(MGraph Graph,int dist[],int path[],Vertex S)
{
int collected[MaxVertexNum];
Vertex V,W;
//初始化
for(V=0;V<Graph->Nv ;V++){
dist[V]=Graph->G[S][V];
if(dist[V]<INFINITY)
path[V]=S;
else
path[V]=-1;
collected[V]=false;
}
//先将起点收入集合
dist[S]=0;
collected[S]=true;
while(1){
V=FindMinDist(Graph,dist,collected);
if(V==ERROR)//V不存在
break;
collected[V]=true;//收录V
for(W=0;W<Graph->Nv ;W++){//对图中的每一个顶点
// 若W是V的邻接点且未被收录
if(collected[W]==false&&Graph->G [V][W]<INFINITY){
if(Graph->G[V][W]<0)//有负边,返回错误标记
return false;
else if(dist[V]+Graph->G[V][W]<dist[W]){
dist[W]=dist[V]+Graph->G[V][W];
path[W]=V;//更新S到W的路径
}
}
//printf("dist[%d]=%d\n",W,dist[W]);
}
}//while循环结束
printf("dist=%d\n",dist[W-1]);
return true;
}
二、完整代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxVertexNum 100 //最大顶点数
#define INFINITY 65535 //∞设为双字节无符号整型的最大值65535
#define ERROR -1
typedef int Vertex; //用顶点下标表示顶点,为整型
typedef int WeightType; //边的权值设为整型
typedef char DataType; //顶点存储的数据类型为字符型
/*-----------图的定义-------------*/
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;//顶点数
int Ne; //边数
WeightType G[MaxVertexNum][MaxVertexNum]; //邻接矩阵
DataType Data[MaxVertexNum];//存顶点的数据
};
typedef PtrToGNode MGraph; //以邻接矩阵存储的图的类型
/*-----------边的定义-------------*/
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1,V2;//有向边<V1,V2>
WeightType Weight; //权值
};
typedef PtrToENode Edge;
/*-----------创建-------------*/
MGraph CreateGraph(int VertexNum)
{//创建一个包含全部顶点的无边图
Vertex V,W;
MGraph Graph;
Graph=(MGraph)malloc(sizeof(struct GNode));
Graph->Nv =VertexNum;
Graph->Ne =0;
//初始化邻接矩阵
//顶点编号从0-Graph->Nv-1
for(V=0;V<Graph->Nv;V++)
for(W=0;W<Graph->Nv;W++)
Graph->G[V][W]=INFINITY;//都为∞
// PrintResult(Graph);
return Graph;
}
/*-----------插入-------------*/
void InsertEdge(MGraph Graph,Edge E)
{//逐条插入边
//插入边<V1,V2>
Graph->G [E->V1 ][E->V2 ]=E->Weight ;
//若是无向图,还需要插入边<V2,V1>
Graph->G [E->V2 ][E->V1 ]=E->Weight ;
}
/*-----------读入数据创建图-------------*/
MGraph BuildGraph()
{
MGraph Graph;
Edge E;
Vertex V;
int Nv,i;
printf("请输入图的顶点数:");
scanf("%d",&Nv);
Graph=CreateGraph(Nv);//初始化有Nv个顶点但没有边的图
printf("请输入边的个数:");
scanf("%d",&(Graph->Ne));
if(Graph->Ne !=0){//有边
//插入边的起点,终点,权值
printf("请输入%d个边的起点 终点 权值:\n",Graph->Ne );
E=(Edge)malloc(sizeof(struct ENode));//开辟空间
for(i=0;i<Graph->Ne ;i++){
printf("%d : ",i);
scanf("%d %d %d",&E->V1,&E->V2 ,&E->Weight );
InsertEdge(Graph,E);
}
}
//如果顶点有数据的话,读入数据
//for(V=0;V<Graph->Nv ;V++)
// scanf("%c",&(Graph->Data[V]));
return Graph;
}
/*------------Dijkstra算法--------------*/
Vertex FindMinDist(MGraph Graph,int dist[],int collected[])
{
//返回未被收录顶点中的dist最小者
Vertex MinV,V;
int MinDist=INFINITY;
for(V=0;V<Graph->Nv ;V++){
if(collected[V]==false&&dist[V]<MinDist){
//若V未被收录并且权值更小
MinDist=dist[V];//更新权值
MinV=V;//更新对应顶点
}
}
if(MinDist<INFINITY)//找到最小权值
return MinV;//返回对应顶点
else return ERROR;
}
bool Dijkstra(MGraph Graph,int dist[],int path[],Vertex S)
{
int collected[MaxVertexNum];
Vertex V,W;
//初始化
for(V=0;V<Graph->Nv ;V++){
dist[V]=Graph->G[S][V];
if(dist[V]<INFINITY)
path[V]=S;
else
path[V]=-1;
collected[V]=false;
}
//先将起点收入集合
dist[S]=0;
collected[S]=true;
while(1){
V=FindMinDist(Graph,dist,collected);
if(V==ERROR)//V不存在
break;
collected[V]=true;//收录V
for(W=0;W<Graph->Nv ;W++){//对图中的每一个顶点
// 若W是V的邻接点且未被收录
if(collected[W]==false&&Graph->G [V][W]<INFINITY){
if(Graph->G[V][W]<0)//有负边,返回错误标记
return false;
else if(dist[V]+Graph->G[V][W]<dist[W]){
dist[W]=dist[V]+Graph->G[V][W];
path[W]=V;//更新S到W的路径
}
}
//printf("dist[%d]=%d\n",W,dist[W]);
}
}//while循环结束
printf("dist=%d\n",dist[W-1]);
return true;
}
void PrintResult(MGraph Graph)
{
printf("邻接矩阵:\n");
int V,W;
for(V=0;V<Graph->Nv ;V++){
for(W=0;W<Graph->Nv ;W++){
if(Graph->G[V][W]==INFINITY)printf("∞ ");
else printf("%d ",Graph->G[V][W]);
}
printf("\n");
}
}
int main()
{
MGraph Graph;
Graph=BuildGraph();
PrintResult(Graph);
int dist[MaxVertexNum];
int path[MaxVertexNum];
Dijkstra(Graph,dist,path,0);
return 0;
}
三、运行