迪杰斯特拉算法c语言实现
简介
原理:路径长度依次递增原理。
辅助向量:
D[]:记录带权长度。每一轮都在向小的值或者不变的值更新。
P[]用来存放前驱顶点。
final[]用来存放某顶点是否已经进入S(已经求得最短路径的顶点集合)集合。
测试用例,一个无向图
其邻接矩阵图:
源码
/************************
*最短路径之dijkstra
*D[]用来存放带权长度。每一轮都在向小的值或者不变的值更新。
*P[]用来存放前驱顶点
*final[]用来存放某顶点是否已经进入S(已经求得V0到Vw的最短路径。)集合。final[w]=1表示已经求得顶点V0到Vw的最短路径 ,即w已经进入S集合了。
******************************************************/
#include<stdio.h>
#include<stdlib.h>
#define MAXVER 100 //最大顶点数
#define INFINITY 65535 //65535表示无穷大(邻接表中 权为无穷大表示没有弧)
typedef int Patharc[MAXVER]; // 用于存储最短路径下标的数组
typedef int ShortPathTable[MAXVER]; // 用于存储到各点最短路径的权值和
typedef struct MGraph
{
char vertex[MAXVER] ; //顶点表
int arc[MAXVER][MAXVER] ;//邻接矩阵
int numVertexes, numEdges;//图中当前顶点数和边数
}MGraph;
//建立无向网的邻接矩阵
void CreateGraph(MGraph *G)
{
int i, j,k,w;
//设置顶点个数
printf("请输入图的顶点数,边数:\n");
scanf("%d %d", &G->numVertexes, &G->numEdges);
//getchar();//清空缓冲区(主要是回车)
setbuf(stdin, NULL);//设置输入缓冲区 为空缓冲区
//设置结点存储值
for (i = 0; i < G->numVertexes; i++)
{
printf("\n请输入第%d个顶点存储的值:",i);
scanf("%c", &G->vertex[i]);
// printf("%c",G->vertex[i]);
setbuf(stdin, NULL);//设置输入缓冲区 为空缓冲区(每次输入一个回车,这里会造成 \n字符存在缓冲区)
}
for (i = 0; i < G->numVertexes; i++)
{
for (j = 0; j < G->numVertexes; j++)
{
if(i == j)
{
G->arc[i][j] = 0;
}
else
{
G->arc[i][j] = INFINITY;//初始化邻接矩阵(权为INFINITY无穷大表示没有弧)
}
}
}
for (k = 0; k < G->numEdges; k++)
{
printf("请输入边(vi,vj)的下标i,下标j对应的权w:");
scanf("%d %d %d", &i, &j, &w);
G->arc[i][j] = w;//设置对应的权
G->arc[j][i] = G->arc[i][j];//无向网,对称矩阵
}
}
void ShortestPath_Dijkstra(MGraph G ,int V0,Patharc *P,ShortPathTable *D)
{
int v,w,k,min;
int final[MAXVER]; //final[w]=1表示已经求得顶点V0到Vw的最短路径 ,即w已经进入S集合了。
//初始化数据
for(v=0;v<G.numVertexes;v++)
{
final[v]=0;
(*D)[v] = G.arc[V0][v];
(*P)[v] = 0;
}
(*D)[V0] = 0; //V0到V0的路径为0
final[V0] = 1; //V0到V0不需要求路径
//开始主循环,每次求得V0到某个V顶点的最短路径。
for(v=1 ;v<G.numVertexes;v++)
{
min =INFINITY;
for(w=0;w<G.numVertexes;w++)
{
if(!final[w] && (*D)[w] <min)
{
k = w;
min = (*D)[w];
}
}
final[k] = 1; // 将目前找到的最近顶点置1
//修正当前最短路径及距离。
for(w=0;w<G.numVertexes;w++)
{
//如果经过V顶点的路径比现在这条路径的长度短的话,更新!
if(!final[w] && min+G.arc[k][w]<(*D)[w])
{
(*D)[w] = min+G.arc[k][w]; //修改当前路径长度
(*P)[w] = k; // 存放前驱结点。
}
}
}
//输出数组D,P,final
printf("\nD 数组的值:");
for(v=0 ;v<G.numVertexes;v++)
{
printf("%d ",(*D)[v]);
}
printf("\nP数组的值:");
for(v=0 ;v<G.numVertexes;v++)
{
printf("%d ",(*P)[v]);
}
printf("\nfinal数组的值:");
for(v=0 ;v<G.numVertexes;v++)
{
printf("%d ",final[v]);
}
}
int main()
{
MGraph G;
CreateGraph(&G);
Patharc P[MAXVER];
ShortPathTable D[MAXVER];
ShortestPath_Dijkstra(G,0,P,D);
system("pause");
return 0;
}