1.实验名称: 采用狄克斯特拉算法求代权有向图的最短路径
2.实验内容:实现求带权有向图中单元最短路径的狄克斯特拉算法,并输出如图所示的带权有向图G中从顶点0到达其他各顶点的最短路径长度最短路径。
3.算法和UML图
void CreateMat(MatGraph &g, int A[MAXV][MAXV], int n, int e)
{
int i, j;
g.n = n;
g.e = e;
for(i = 0; i < g.n; i++)
for(j = 0; j < g.n; j++)
g.edges[i][j] = A[i][j];
}
void Dispath(MatGraph g, int dist[], int path[], int S[], int v)
{
int i, j, k;
int apath[MAXV], d; //存放一条最短路径(逆向)及其顶点个数
for(i = 0; i < g.n; i++) //循环输出从顶点v到i的路径
{
if(S[i] == 1 && i != v)
{
printf(" 从顶点%d到顶点%d的路径长度为:%d\t路径为:", v, i, dist[i]);
d = 0; apath[d] = i; //添加路径上的终点
k = path[i];
if(k == -1) //没有路径的情况
printf("无路径\n");
else //存在路径时输出该路径
{
while(k != v)
{
d++;
apath[d] = k;
k = path[k];
}
d++; apath[d] = v; //添加路径上的起点
printf("%d", apath[d]); //先输出起点
for(j = d - 1; j >= 0; j--) //再输出其余顶点
printf(", %d", apath[j]);
printf("\n");
}
}
}
}
void Dijstra(MatGraph g, int v)
{
int dist[MAXV], path[MAXV];
int S[MAXV]; //S[i]=1表示顶点i在S中,S[i]=0表示顶点i在U中
int i, j, u;
int Mindis;
for(i = 0; i < g.n; i++)
{
dist[i] = g.edges[v][i]; //距离初始化
S[i] = 0; //S[i]置0
if(g.edges[v][i] < INf) //路径初始化
path[i] = v;
else
path[i] = -1;
}
//源点编号v放入S中
S[v] = 1;
path[v] = 0;
for(i = 0; i < g.n - 1; i++) //循环直到所有顶点的最短路径都求出
{
Mindis = INf; //Mindis置最大长度初值
for(j = 0; j < g.n; j++)
{
if(S[j] == 0 && dist[j] < Mindis)
{
u = j;
Mindis = dist[j];
}
}
//顶点u加入S中
S[u] = 1;
//修改不在S中(即U中)的顶点的最短路径
for(j = 0; j < g.n; j++)
{
if(S[j] == 0)
{
if((g.edges[u][j] < INf) && (dist[u] + g.edges[u][j] < dist[j]))
{
dist[j] = dist[u] + g.edges[u][j];
path[j] = u;
}
}
}
}
//输出最短路径
Dispath(g, dist, path, S, v);
}
UML图
4.源程序
#include <stdio.h>
#include <malloc.h>
#define MAXV 6
#define INf 32767
//邻接矩阵类型声明
typedef struct
{
int no;//
// InfoType info;
}VertexType;
typedef struct
{
int edges[MAXV][MAXV];
int n,e;
VertexType vexs[MAXV];
}MatGraph;
int A[MAXV][MAXV]={
{0,5,INf,7,INf,INf},{INf,0,4,INf,INf,INf},
{8,INf,0,INf,INf,9},{INf,INf,5,0,INf,6},
{INf,INf,INf,5,0,INf},{3,INf,INf,INf,1,0},
};
void CreateMat(MatGraph &g, int A[MAXV][MAXV], int n, int e)
{
int i, j;
g.n = n;
g.e = e;
for(i = 0; i < g.n; i++)
for(j = 0; j < g.n; j++)
g.edges[i][j] = A[i][j];
}
void Dispath(MatGraph g, int dist[], int path[], int S[], int v)
{
int i, j, k;
int apath[MAXV], d; //存放一条最短路径(逆向)及其顶点个数
for(i = 0; i < g.n; i++) //循环输出从顶点v到i的路径
{
if(S[i] == 1 && i != v)
{
printf(" 从顶点%d到顶点%d的路径长度为:%d\t路径为:", v, i, dist[i]);
d = 0; apath[d] = i; //添加路径上的终点
k = path[i];
if(k == -1) //没有路径的情况
printf("无路径\n");
else //存在路径时输出该路径
{
while(k != v)
{
d++;
apath[d] = k;
k = path[k];
}
d++; apath[d] = v; //添加路径上的起点
printf("%d", apath[d]); //先输出起点
for(j = d - 1; j >= 0; j--) //再输出其余顶点
printf(", %d", apath[j]);
printf("\n");
}
}
}
}
void Dijstra(MatGraph g, int v)
{
int dist[MAXV], path[MAXV];
int S[MAXV]; //S[i]=1表示顶点i在S中,S[i]=0表示顶点i在U中
int i, j, u;
int Mindis;
for(i = 0; i < g.n; i++)
{
dist[i] = g.edges[v][i]; //距离初始化
S[i] = 0; //S[i]置0
if(g.edges[v][i] < INf) //路径初始化
path[i] = v;
else
path[i] = -1;
}
//源点编号v放入S中
S[v] = 1;
path[v] = 0;
for(i = 0; i < g.n - 1; i++) //循环直到所有顶点的最短路径都求出
{
Mindis = INf; //Mindis置最大长度初值
for(j = 0; j < g.n; j++)
{
if(S[j] == 0 && dist[j] < Mindis)
{
u = j;
Mindis = dist[j];
}
}
//顶点u加入S中
S[u] = 1;
//修改不在S中(即U中)的顶点的最短路径
for(j = 0; j < g.n; j++)
{
if(S[j] == 0)
{
if((g.edges[u][j] < INf) && (dist[u] + g.edges[u][j] < dist[j]))
{
dist[j] = dist[u] + g.edges[u][j];
path[j] = u;
}
}
}
}
//输出最短路径
Dispath(g, dist, path, S, v);
}
int main()
{
MatGraph g;
CreateMat(g,A,6,10);
Dijstra(g,0);
return 0;
}
5.实验截图
6.实验小结
1.实验中遇到了什么问题及其解决过程。
机房电脑出故障,导致我第一次敲的代码全没了,清得一干二净。解决方法就是换台电脑。在定义矩阵数组时,采用了全局定义的方式,在引用的时候并没有把矩阵的数据传进去,需要定义一个函数把图的相关数据传入。
2.实验中产生的错误及其分析原因(写出执行语句不成功的时候系统报告的错误信息。然后分析错误原因,并给出解决办法。
- 单词拼写出错
- 遗漏了个别标点符号