#include #include #include #define Infinity 999 //最大值 #define Max_Vertex_Num 20 //顶点数最多为20 #define Len sizeof(struct arcNode) #define gLen sizeof(struct Graph) #define HIT_Ver_Num 11 //共有11个顶点 #define HIT_Arc_Num 18 //共有18个边 //边节点 struct arcNode{ int adjvex; //该边所指向的顶点位置 struct arcNode *nextArc; //指向下一条边的指针 int value; //边的权值 }; //顶点节点 typedef struct verNode{ char *data; //顶点信息 struct arcNode *firstArc; //指向第一条依附该顶点的边 }verNode,adjList[Max_Vertex_Num]; //图的邻接表存储类型 struct Graph{ int g_arcs[Max_Vertex_Num][Max_Vertex_Num]; adjList vertices; //声明一个存储顶点的数组 int vexNum,arcNum; //vexNum 是顶点数,arcNum 是边数 }; struct Graph * creatGraph() { int i,j,a,b; struct Graph *graph = (struct Graph *)malloc(gLen); struct arcNode *arc_1 = (struct arcNode *)malloc(Len);//N楼 struct arcNode *arc_2 = (struct arcNode *)malloc(Len); struct arcNode *arc_3 = (struct arcNode *)malloc(Len); struct arcNode *arc_4 = (struct arcNode *)malloc(Len);//食堂 struct arcNode *arc_5 = (struct arcNode *)malloc(Len); struct arcNode *arc_6 = (struct arcNode *)malloc(Len); struct arcNode *arc_7 = (struct arcNode *)malloc(Len);//教师公寓 struct arcNode *arc_8 = (struct arcNode *)malloc(Len); struct arcNode *arc_9 = (struct arcNode *)malloc(Len);//M楼 struct arcNode *arc_10 = (struct arcNode *)malloc(Len); struct arcNode *arc_11 = (struct arcNode *)malloc(Len); struct arcNode *arc_12 = (struct arcNode *)malloc(Len);//G楼 struct arcNode *arc_13 = (struct arcNode *)malloc(Len); struct arcNode *arc_14 = (struct arcNode *)malloc(Len); struct arcNode *arc_15 = (struct arcNode *)malloc(Len); struct arcNode *arc_16 = (struct arcNode *)malloc(Len); struct arcNode *arc_17 = (struct arcNode *)malloc(Len); struct arcNode *arc_18 = (struct arcNode *)malloc(Len);//主楼 struct arcNode *arc_19 = (struct arcNode *)malloc(Len); struct arcNode *arc_20 = (struct arcNode *)malloc(Len); struct arcNode *arc_21 = (struct arcNode *)malloc(Len);//H楼 struct arcNode *arc_22 = (struct arcNode *)malloc(Len); struct arcNode *arc_23 = (struct arcNode *)malloc(Len); struct arcNode *arc_24 = (struct arcNode *)malloc(Len);//体育场 struct arcNode *arc_25 = (struct arcNode *)malloc(Len); struct arcNode *arc_26 = (struct arcNode *)malloc(Len); struct arcNode *arc_27 = (struct arcNode *)malloc(Len);//校训石 struct arcNode *arc_28 = (struct arcNode *)malloc(Len); struct arcNode *arc_29 = (struct arcNode *)malloc(Len); struct arcNode *arc_30 = (struct arcNode *)malloc(Len); struct arcNode *arc_31 = (struct arcNode *)malloc(Len);//研究院 struct arcNode *arc_32 = (struct arcNode *)malloc(Len); struct arcNode *arc_33 = (struct arcNode *)malloc(Len); struct arcNode *arc_34 = (struct arcNode *)malloc(Len);//学校正门 struct arcNode *arc_35 = (struct arcNode *)malloc(Len); struct arcNode *arc_36 = (struct arcNode *)malloc(Len); char *Data[HIT_Ver_Num] = {"N楼","食堂","教师公寓","M楼","G楼","主楼","H楼","体育场","校训石","研究院","学校正门"}; if(graph==NULL||arc_1==NULL||arc_2==NULL||arc_3==NULL||arc_4==NULL||arc_5==NULL||arc_6==NULL||arc_7==NULL||arc_8==NULL||arc_9==NULL ||arc_10==NULL||arc_11==NULL||arc_12==NULL||arc_13==NULL||arc_14==NULL||arc_15==NULL||arc_16==NULL||arc_17==NULL||arc_18==NULL ||arc_19==NULL||arc_20==NULL||arc_21==NULL||arc_22==NULL||arc_23==NULL||arc_24==NULL||arc_25==NULL||arc_26==NULL||arc_27==NULL ||arc_28==NULL||arc_29==NULL||arc_30==NULL||arc_31==NULL||arc_32==NULL||arc_33==NULL||arc_34==NULL||arc_35==NULL||arc_36==NULL) { printf("内存不足\n退出程序"); exit(0); } graph->vexNum = HIT_Ver_Num; graph->arcNum = HIT_Arc_Num; for(j = 0; j < graph->vexNum; j++) { graph->vertices[j].data = Data[j]; graph->vertices[j].firstArc = NULL; } arc_1->value = 130; arc_1->adjvex = 3; arc_1->nextArc = graph->vertices[0].firstArc; graph->vertices[0].firstArc = arc_1; arc_2->value = 140; arc_2->adjvex = 4; arc_2->nextArc = graph->vertices[0].firstArc; graph->vertices[0].firstArc = arc_2; arc_3->value = 55; arc_3->adjvex = 1; arc_3->nextArc = graph->vertices[0].firstArc; graph->vertices[0].firstArc = arc_3;//End N楼 arc_4->value = 55; arc_4->adjvex = 0; arc_4->nextArc = graph->vertices[1].firstArc; graph->vertices[1].firstArc = arc_4; arc_5->value = 150; arc_5->adjvex = 4; arc_5->nextArc = graph->vertices[1].firstArc; graph->vertices[1].firstArc = arc_5; arc_6->value = 110; arc_6->adjvex = 2; arc_6->nextArc = graph->vertices[1].firstArc; graph->vertices[1].firstArc = arc_6;//End 食堂 arc_7->value = 110; arc_7->adjvex = 1; arc_7->nextArc = graph->vertices[2].firstArc; graph->vertices[2].firstArc = arc_7; arc_8->value = 105; arc_8->adjvex = 6; arc_8->nextArc = graph->vertices[2].firstArc; graph->vertices[2].firstArc = arc_8;//End 教师公寓 arc_9->value = 130; arc_9->adjvex = 0; arc_9->nextArc = graph->vertices[3].firstArc; graph->vertices[3].firstArc = arc_9; arc_10->value = 40; arc_10->adjvex = 4; arc_10->nextArc = graph->vertices[3].firstArc; graph->vertices[3].firstArc = arc_10; arc_11->value = 70; arc_11->adjvex = 7; arc_11->nextArc = graph->vertices[3].firstArc; graph->vertices[3].firstArc = arc_11;//End M楼 arc_12->value = 40; arc_12->adjvex = 3; arc_12->nextArc = graph->vertices[4].firstArc; graph->vertices[4].firstArc = arc_12; arc_13->value = 140; arc_13->adjvex = 0; arc_13->nextArc = graph->vertices[4].firstArc; graph->vertices[4].firstArc = arc_13; arc_14->value = 150; arc_14->adjvex = 1; arc_14->nextArc = graph->vertices[4].firstArc; graph->vertices[4].firstArc = arc_14; arc_15->value = 40; arc_15->adjvex = 5; arc_15->nextArc = graph->vertices[4].firstArc; graph->vertices[4].firstArc = arc_15; arc_16->value = 100; arc_16->adjvex = 8; arc_16->nextArc = graph->vertices[4].firstArc; graph->vertices[4].firstArc = arc_16; arc_17->value = 65; arc_17->adjvex = 7; arc_17->nextArc = graph->vertices[4].firstArc; graph->vertices[4].firstArc = arc_17;//End G楼 arc_18->value = 40; arc_18->adjvex = 4; arc_18->nextArc = graph->vertices[5].firstArc; graph->vertices[5].firstArc = arc_18; arc_19->value = 115; arc_19->adjvex = 6; arc_19->nextArc = graph->vertices[5].firstArc; graph->vertices[5].firstArc = arc_19; arc_20->value = 50; arc_20->adjvex = 8; arc_20->nextArc = graph->vertices[5].firstArc; graph->vertices[5].firstArc = arc_20;//End 主楼 arc_21->value = 105; arc_21->adjvex = 2; arc_21->nextArc = graph->vertices[6].firstArc; graph->vertices[6].firstArc = arc_21; arc_22->value = 115; arc_22->adjvex = 5; arc_22->nextArc = graph->vertices[6].firstArc; graph->vertices[6].firstArc = arc_22; arc_23->value = 60; arc_23->adjvex = 9; arc_23->nextArc = graph->vertices[6].firstArc; graph->vertices[6].firstArc = arc_23;//End H楼 arc_24->value = 70; arc_24->adjvex = 3; arc_24->nextArc = graph->vertices[7].firstArc; graph->vertices[7].firstArc = arc_24; arc_25->value = 65; arc_25->adjvex = 4; arc_25->nextArc = graph->vertices[7].firstArc; graph->vertices[7].firstArc = arc_25; arc_26->value = 100; arc_26->adjvex = 10; arc_26->nextArc = graph->vertices[7].firstArc; graph->vertices[7].firstArc = arc_26;//End 体育场 arc_27->value = 100; arc_27->adjvex = 4; arc_27->nextArc = graph->vertices[8].firstArc; graph->vertices[8].firstArc = arc_27; arc_28->value = 50; arc_28->adjvex = 5; arc_28->nextArc = graph->vertices[8].firstArc; graph->vertices[8].firstArc = arc_28; arc_29->value = 50; arc_29->adjvex = 9; arc_29->nextArc = graph->vertices[8].firstArc; graph->vertices[8].firstArc = arc_29; arc_30->value = 40; arc_30->adjvex = 10; arc_30->nextArc = graph->vertices[8].firstArc; graph->vertices[8].firstArc = arc_30;//End 校训石 arc_31->value = 50; arc_31->adjvex = 8; arc_31->nextArc = graph->vertices[9].firstArc; graph->vertices[9].firstArc = arc_31; arc_32->value = 60; arc_32->adjvex = 6; arc_32->nextArc = graph->vertices[9].firstArc; graph->vertices[9].firstArc = arc_32; arc_33->value = 70; arc_33->adjvex = 10; arc_33->nextArc = graph->vertices[9].firstArc; graph->vertices[9].firstArc = arc_33;//End 研究院 arc_34->value = 100; arc_34->adjvex = 7; arc_34->nextArc = graph->vertices[10].firstArc; graph->vertices[10].firstArc = arc_34; arc_35->value = 40; arc_35->adjvex = 8; arc_35->nextArc = graph->vertices[10].firstArc; graph->vertices[10].firstArc = arc_35; arc_36->value = 70; arc_36->adjvex = 9; arc_36->nextArc = graph->vertices[10].firstArc; graph->vertices[10].firstArc = arc_36;//End 学校正门 for(a = 0; a < graph->vexNum; a++) //置为无穷大(999) { for(b = 0; b < graph->vexNum; b++) { graph->g_arcs[a][b] = Infinity; } } for(i = 0; i < graph->vexNum; i++) //将相应位置置权值 { while(graph->vertices[i].firstArc != NULL) { graph->g_arcs[i][graph->vertices[i].firstArc->adjvex] = graph->vertices[i].firstArc->value; graph->vertices[i].firstArc = graph->vertices[i].firstArc->nextArc; } } return graph; } //单源最短路径(即 Dijkstra算法) void shortestPath_Dij(struct Graph graph,int v0) { int i = 0,v,w,min,pre; int arrayD[HIT_Ver_Num],arrayP[HIT_Ver_Num];//辅助数组 int arrayFinal[HIT_Ver_Num];//辅助数组 //初始化 for(v = 0; v < graph.vexNum; v++) { arrayFinal[v] = 0; arrayD[v] =graph.g_arcs[v0][v]; if(arrayD[v] < Infinity) { arrayP[v] = v0; } else { arrayP[v] = -1; } } arrayFinal[v0] = 1; arrayP[v0] = -1; for(i = 1; i < graph.vexNum; i++) { min = Infinity; //加入具有最小代价的邻居节点 for(w = 0; w < graph.vexNum; w++) { if(!arrayFinal[w] && (arrayD[w] < min)) { v = w; min = arrayD[w]; } } arrayFinal[v] = 1; //计算加入新的节点后,更新路径使得其产生代价最短 for(w = 0; w < graph.vexNum; w++) { if(!arrayFinal[w] && (min + graph.g_arcs[v][w] < arrayD[w])) { arrayD[w] = min + graph.g_arcs[v][w]; arrayP[w] = v; } } } for(i = 0; i < graph.vexNum; i++) { if(v0 == i) printf("目的地与起点重合,权值为零\n\n"); else { printf("权值为:%d\n",arrayD[i]); printf("%s",graph.vertices[i].data); pre = arrayP[i]; while(pre != -1) { printf(" <-- %s",graph.vertices[pre].data); pre = arrayP[pre]; } printf("\n\n"); } } } void shortestPath_Floyd(struct Graph graph,int v1,int v2) { int i,j,k,temp; int arrayPath[HIT_Ver_Num][HIT_Ver_Num],arrayDis[HIT_Ver_Num][HIT_Ver_Num]; //初始化 for(i = 0; i < graph.vexNum; i++) { for(j = 0; j < graph.vexNum; j++) { if(graph.g_arcs[i][j] < Infinity) arrayPath[i][j] = j; else arrayPath[i][j] = -1; arrayDis[i][j] = graph.g_arcs[i][j]; } } for(k = 0; k < graph.vexNum; k++)//对所有顶点进行试探 { for(i = 0; i < graph.vexNum; i++) { for(j = 0; j < graph.vexNum; j++) { if(arrayDis[i][j] > arrayDis[i][k] + arrayDis[k][j]) { arrayDis[i][j] = arrayDis[i][k] + arrayDis[k][j];//取较小者 arrayPath[i][j] = arrayPath[i][k];//改Vi的后继 } } } } printf("从 %s 到 %s 的最短距离为:%d\n",graph.vertices[v1].data,graph.vertices[v2].data,arrayDis[v1][v2]); printf("最短路径为:\t"); temp = arrayPath[v1][v2]; printf("%s --> ",graph.vertices[v1].data);//输出V1 while(temp != v2)//temp不等于路径终点v2时 { printf("%s --> ",graph.vertices[temp].data);//输出 temp = arrayPath[temp][v2];//求路径上下一顶点 } printf("%s.",graph.vertices[v2].data);//输出V2 printf("\n"); } int main() { int b,c,count = 0; int num,i,a,i_2,i_3; char *nodeName_1 = (char*)malloc(10);//必须得用malloc函数申请空间 char *nodeName_2 = (char*)malloc(10);//必须得用malloc函数申请空间 char *nodeName_3 = (char*)malloc(10);//必须得用malloc函数申请空间 struct Graph *graph; graph = creatGraph(); //生成图 for(b=0;bvexNum;b++) { for(c = 0;cvexNum;c ++) { printf("%d\t",graph->g_arcs[b][c]); } printf("\n"); } printf("请按提示进行操作:\n"); printf("1、输入任意一个节点的名称,显示它到各个节点的最短路径及最短距离。\n"); printf("2、输入任意两个节点的名称,显示两点间最短路径和最短距离。\n"); printf("请输入 1 或 2 进行查询。\n"); scanf("%d",&num); switch(num) { case 1: for(a = 0;avexNum;a++) { printf("%s ",graph->vertices[a].data); } printf("\n"); printf("请输入节点名称:\n"); scanf("%s",nodeName_1); for(i = 0; i < graph->vexNum; i++) { if(strcmp(nodeName_1,graph->vertices[i].data) != 0) { count++; } if(0 == strcmp(nodeName_1,graph->vertices[i].data)) { shortestPath_Dij(*graph,i); } } if(graph->vexNum == count) { printf("输入名称有误!退出程序!"); exit(0); } break; case 2: for(a = 0;avexNum;a++) { printf("%s ",graph->vertices[a].data); } printf("\n"); printf("请分别输入第一个节点名称:\n"); scanf("%s",nodeName_2); printf("请分别输入第二个节点名称:\n"); scanf("%s",nodeName_3); for(i = 0; i < graph->vexNum; i++) { if(0 == strcmp(nodeName_2,graph->vertices[i].data)) { i_2 = i; } if(0 == strcmp(nodeName_3,graph->vertices[i].data)) { i_3 = i; } } if(i_2 == i_3) { printf("输入的起点和终点重合,退出程序!"); exit(0); } shortestPath_Floyd(*graph,i_2,i_3); break; default: printf("输入有误!退出程序!"); exit(0); break; } return 0; }
实验结果: