#用c语言实现迪克斯特拉算法
求最短路已有成熟的算法,如迪克斯特拉算法,其思想就是从按距离从近到远,依次求得到各个顶点的最短距离。
首先,构建结构体,其代码如下:
struct Dijkstra {
int w[Maxsize][Maxsize]; //权重距离矩阵
int l[Maxsize]; //依次求得各点到起点的最短距离
int s; //顶点个数
}path;
然后,我们将从键盘输入的距离矩阵整理,并输出:
void Dijkstra_mat()
{
for (int i = 0; i < path.s; i++)
{
for (int j = 0; j < path.s; j++)
{
printf("%-6d", path.w[i][j]);
}
printf("\n");
}
printf("********************\n");
}
我们知道,迪克斯特算法的核心就是更新赋值矩阵,求得最短的路径,因此,我们需要更新最短路,其代码如下:
int min(int a, int b) //更新赋值路
{
if (a <= b)
return a;
if (a > b)
return b;
}
在c语言中,运用迪克斯特拉算法的核心部分,并以此调用以上函数,可得代码为:
void Dijkstra()
{
int u = 0, v; //u为起点,v为距u最短点
for (int i = 0; i < path.s; i++)
{
for (int v = 0; v < path.s; v++)
{
path.l[v] = min(path.l[v], path.l[u] + path.w[u][v]);
}
u = the_mins(u);
i++;
}
for (int j = 0; j < path.s; j++)
{
printf("到第%d个地方的距离为%4d\n", j + 1, path.l[j]);
}
}
主函数的作用为对距离矩阵赋值,并调用其他函数,最终得到完整的迪克斯特拉算法:
int main()
{
int path_sum = 0; //最初的路径为0
printf("请输入顶点个数:");
scanf_s("%d", &path.s);
printf("请输入距离矩阵:");
for (int i = 0; i < path.s; i++) //距离赋权矩阵赋值
{
for (int j = 0; j < path.s; j++)
{
scanf_s("%d", &path.w[i][j]);
if (path.w[i][j] == -1)
path.w[i][j] = INF;
printf(" ");
}
printf("\n");
}
for (int i = 0; i < path.s; i++)
{
if (i == 0)
path.l[i] = 0;
else
path.l[i] = INF;
}
printf("得到的距离矩阵为:\n");
Dijkstra_mat();
Dijkstra();
}
得到的完整代码:
#include<stdio.h>
#define INF 9999
#define Maxsize 50
struct Dijkstra {
int w[Maxsize][Maxsize]; //权重距离矩阵
int l[Maxsize]; //依次求得各点到起点的最短距离
int s; //顶点个数
}path;
int min(int a, int b) //更新赋值路
{
if (a <= b)
return a;
if (a > b)
return b;
}
void Dijkstra_mat()
{
for (int i = 0; i < path.s; i++)
{
for (int j = 0; j < path.s; j++)
{
printf("%-6d", path.w[i][j]);
}
printf("\n");
}
printf("********************\n");
}
int the_mins(int u) //以距离上一个点最短的点为起点
{
int v = u, j = 0;
int min, step;
for (int i = 0; i < path.s; i++)
{
if (path.l[i] > path.l[u])
{
j++;
if (j == 1)
{
step = path.l[i];
min = path.l[i];
v = i;
}
if (path.l[i] < step)
{
min = path.l[i];
v = i;
}
}
}
return v;
}
void Dijkstra()
{
int u = 0, v; //u为起点,v为距u最短点
for (int i = 0; i < path.s; i++)
{
for (int v = 0; v < path.s; v++)
{
path.l[v] = min(path.l[v], path.l[u] + path.w[u][v]);
}
u = the_mins(u);
i++;
}
for (int j = 0; j < path.s; j++)
{
printf("到第%d个地方的距离为%4d\n", j + 1, path.l[j]);
}
}
int main()
{
int path_sum = 0; //最初的路径为0
printf("请输入顶点个数:");
scanf_s("%d", &path.s);
printf("请输入距离矩阵:");
for (int i = 0; i < path.s; i++) //距离赋权矩阵赋值
{
for (int j = 0; j < path.s; j++)
{
scanf_s("%d", &path.w[i][j]);
if (path.w[i][j] == -1)
path.w[i][j] = INF;
printf(" ");
}
printf("\n");
}
for (int i = 0; i < path.s; i++)
{
if (i == 0)
path.l[i] = 0;
else
path.l[i] = INF;
}
printf("得到的距离矩阵为:\n");
Dijkstra_mat();
Dijkstra();
}
例如,我们可运用以上代码求出下图的最短距离
调用该函数,我们得到