#include <stdio.h>
#include <stdlib.h>
#define MAXDISTANCE 9999//假如两个顶点没有 直接 的路径,它们之间的权值就用这个来表示
#define MAX_VERT_NUM 10
typedef int Bool;
#define False 0
#define True 1
struct Graph {
char verts[MAX_VERT_NUM];
int edgs[MAX_VERT_NUM][MAX_VERT_NUM];
int vertnum;
int edgnum;
};
struct Graph init(void);
void printEdg(struct Graph g);
void ShortestPath_DIJ(struct Graph g);
struct Graph init(void) {
struct Graph g;
int i, j, k1, k2, weight;
char data1, data2;
int locateVert(struct Graph g, char data);
g.vertnum = 6;
g.edgnum = 8;
//输入顶点和边 printf("请输入图的顶点数:");scanf("%d",&g.vertnum); printf("请输入图的边数:"); scanf("%d",&g.edgnum);
for (i = 0; i<g.vertnum; i++) {
g.verts[i] = char(i + 48);
//输入 printf("请输入第%d个顶点:",i+1);scanf(" %c",&g.verts[i]);
}
for (i = 0; i<g.vertnum; i++) {
for (j = 0
; j<g.vertnum; j++) {
g.edgs[i][j] = MAXDISTANCE;//先给边赋上最大的权值
}
}
char data[7][1];
int w[8];
data[0][0] = '0'; data[0][1] = '1';
data[1][0] = '0'; data[1][1] = '2';
data[2][0] = '0'; data[2][1] = '3';
data[3][0] = '1'; data[3][1] = '2';
data[4][0] = '1'; data[4][1] = '4';
data[5][0] = '2'; data[5][1] = '5';
data[6][0] = '3'; data[6][1] = '5';
data[7][0] = '4'; data[7][1] = '5';
data2 = data[7][1];
printf("%d\n",data2);
w[0] = 1; w[1] = 5; w[2] = 2; w[3] = 3; w[4] = 7; w[5] = 6; w[6] = 8; w[7] = 4;
for (j = 0; j<g.edgnum; j++) {
printf("第%d次\n",j+1);
printf("%d\n",&data[j][0]);
printf("%d\n",&data[7][1]); //查看地址
data1 = data[j][0];
printf("%c\n",data1);
data2 = data[j][1];
printf("%c\n",data2);
weight = w[j];
k1 = locateVert(g, data1);
k2 = locateVert(g, data2);
g.edgs[k1][k2] = weight;//对边进行赋权值
}
return g;
}
int locateVert(struct Graph g, char data) {
int i;
for (i = 0; g.verts[i] != data; i++);
if (i>g.vertnum - 1) {
printf("输入的顶点有误");
exit(1);
}
return i;
}
void printEdg(struct Graph g) {
int i, j;
for (i = 0; i<g.vertnum; i++) {
printf("顶点%c:\t", g.verts[i]);
for (j = 0; j<g.vertnum; j++) {
printf("%d\t", g.edgs[i][j]);
if (j == g.vertnum - 1) {
printf("\n");
}
}
}
}
void ShortestPath_DIJ(struct Graph g) {
Bool S[MAX_VERT_NUM];
//S[i]为true,当且仅当第i个顶点属于s,即已经求得从a到第i个顶点的最短路径
Bool p[MAX_VERT_NUM][MAX_VERT_NUM];
//若p[v][w]为True,则w是从a顶点到其余顶点v的最短路径上的顶点
int D[MAX_VERT_NUM];
//为顶点a到该第i个顶点最短路径的权值和
//以上为狄克斯特拉算法的辅助数组
int v, w, i, j, distance = 9999, min, k;
for (v = 0; v<g.vertnum; v++) {
S[v] = False;
D[v] = g.edgs[0][v];
for (w = 0; w<g.vertnum; w++) p[v][w] = False;
if (D[v]<distance) {
p[v][0] = True;
p[v][v] = True;
}
}
D[0] = 0;
S[0] = True;
/*开始主循环,每次求得a到其他顶点距离中最短的一个,并加v到s中,比如第一次求得的是a顶点到c顶点的距离最短,为10,
第二次求得的是a顶点到e顶点的距离最短,为30,以此类推,以后求的都是次短的路径距离*/
for (i = 0; i<g.vertnum; i++) {
min = distance;
for (w = 0; w<g.vertnum; w++) {//循环完之后,求得的是其他顶点到a的最短路径,就是假如c到a是10,b到a是5,那么求得的顶点是b
if (!S[w]) {
if (D[w]<min) {
v = w;
min = D[w];
}
}
}
S[v] = True;//求得a顶点到其他顶点距离中最小的那个顶点后,把该顶点加入到final数组中,代表已经求出来了,下次循环开始求次短的
for (w = 0; w<g.vertnum; w++) {
/*更新其他顶点到a的最短距离,上一步求出到a顶点有最短路径的顶点了,求a顶点通过该顶点到其他顶点的距离,
和他们直接到a顶点的距离相比较,是否需要重新对D[i]赋值*/
if (!S[w] && (min + g.edgs[v][w]<D[w])) {
D[w] = min + g.edgs[v][w];
for (k = 0; k<g.vertnum; k++) {
p[w][k] = p[v][k];
}
p[w][w] = True;//如果a顶点有到w顶点的路径,说明在a顶点到w顶点的路径上,一定包括w顶点
}
}
}
//打印出最后的结果
for (i = 1; i<g.vertnum; i++) {
printf("顶点0到顶点%c的权值是:%d\n", g.verts[i], D[i]);
if (D[i] >= distance) {
printf("没有路径\n");
}
else {
printf("路径:");
for (j = 0; j<g.vertnum; j++) {
if (p[i][j]) {
printf("->%c", g.verts[j]);
}
}
printf("\n");
}
}
}
int main(int argc, const char * argv[]) {
struct Graph g = init();//初始化
printEdg(g);//打印图
ShortestPath_DIJ(g);//打印最短路径
system("pause");
return 0;
}
没设置字符串的终止符,导致第一层数组地址要向前吃掉一个地址再赋值,所以二维数组为000112345
但在struct Graph init函数最后一个循环中最后一次循环因locateVert函数使data[7][1]的值发生突变,由ASC码53变为4;但删去locateVert就正常;这是什么原理