1.1 需求分析
随着社会的发展,越来越多的大学生选择去找同学,游历一些名校,然而到了一个陌生的学校又该怎么样去选择利用更少的时间,走最少的路去游历校园的所有景点呢。此时就需要这块校园交通导游系统了。
程序要求至少包括10个以上的校园建筑物,每两个建筑物可以有不同的路径,并且路长可能不同,要求找出从任意建筑物到达另一建筑物的最短路径。先从文件中读取校园的各个建筑物以及相互之间的路径和路长,构造校园的导游图。其次,根据用户输入的两个建筑物,给出两个建筑物点之间的最短路径。
1.2 运用的数据结构模型
此程序运用了结构体用来存储校园建筑物的编号和建筑物的名称,另用一结构体存储建筑物间的权值;
计算任意两建筑物间路径长度用到的是弗洛伊德算法,通过判断两建筑物间是否路径,然后计算两建筑物间的最短路径。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define INF 32767
#define MAX 16
#define NAME_MAX 20
typedef struct
{
int WEIGHT; //建筑物的权值
char NAME[NAME_MAX]; //建筑物的名字
}View;
typedef struct
{
View Vertex[MAX]; //存储顶点
View Weight[MAX][MAX]; //权值的坐标位置
}MGraph;
void Dispath(MGraph MG, View _Weight[][MAX], View Path[][MAX], int Start, int End);
void CreateMGraph(MGraph *MG)
{
int i, j;
strcpy(MG->Vertex[0].NAME, "校大门"); strcpy(MG->Vertex[1].NAME, "图书馆"); strcpy(MG->Vertex[2].NAME, "老校区操场");
strcpy(MG->Vertex[3].NAME, "6号宿舍"); strcpy(MG->Vertex[4].NAME, "小礼堂"); strcpy(MG->Vertex[5].NAME, "下沉光场");
strcpy(MG->Vertex[6].NAME, "学宛餐厅"); strcpy(MG->Vertex[7].NAME, "专家公寓"); strcpy(MG->Vertex[8].NAME, "教工3村");
strcpy(MG->Vertex[9].NAME, "荷花池"); strcpy(MG->Vertex[10].NAME, "9#教学楼"); strcpy(MG->Vertex[11].NAME, "12#教学楼");
strcpy(MG->Vertex[12].NAME, "15#教学楼"); strcpy(MG->Vertex[13].NAME, "学生广场"); strcpy(MG->Vertex[14].NAME, "网球场");
strcpy(MG->Vertex[15].NAME, "东南餐厅");
for(i = 0; i < MAX; i++) //初始化邻接矩阵
{
for(j = 0; j < MAX; j++)
{
MG->Weight[i][j].WEIGHT = INF;
if(i == j)
{
MG->Weight[i][j].WEIGHT = 0;
}
}
}
MG->Weight[0][1].WEIGHT = 60;MG->Weight[0][2].WEIGHT = 90;MG->Weight[0][3].WEIGHT = 100;MG->Weight[1][2].WEIGHT = 20;
MG->Weight[1][3].WEIGHT = 50;MG->Weight[1][4].WEIGHT = 40;MG->Weight[2][4].WEIGHT = 65;MG->Weight[3][5].WEIGHT = 80;
MG->Weight[4][5].WEIGHT = 55;MG->Weight[5][6].WEIGHT = 50;MG->Weight[5][7].WEIGHT = 100;MG->Weight[6][7].WEIGHT = 130;
MG->Weight[2][8].WEIGHT = 250;MG->Weight[7][8].WEIGHT = 150;MG->Weight[8][9].WEIGHT = 100;MG->Weight[9][10].WEIGHT = 40;
MG->Weight[9][11].WEIGHT = 60;MG->Weight[10][11].WEIGHT = 30;MG->Weight[11][12].WEIGHT = 50;MG->Weight[11][13].WEIGHT = 15;
MG->Weight[10][13].WEIGHT = 75;MG->Weight[12][13].WEIGHT = 45;MG->Weight[12][14].WEIGHT = 160;MG->Weight[13][14].WEIGHT = 100;
MG->Weight[14][15].WEIGHT = 120;
for(i = 0; i < MAX; i++) //对称赋值
{
for(j = i; j < MAX; j++)
{
MG->Weight[j][i].WEIGHT = MG->Weight[i][j].WEIGHT;
}
}
}
void Floyd(MGraph MG, int Start, int End)
{
View _Weight[MAX][MAX], Path[MAX][MAX];
int i, j, k;
for(i = 0; i < MAX; i++)
{
for(j = 0; j < MAX; j++)
{
_Weight[i][j].WEIGHT = MG.Weight[i][j].WEIGHT;
Path[i][j].WEIGHT = -1;
}
}
for(k = 0; k < MAX; k++) //弗洛伊德算法查找最短路径
{
for(i = 0; i < MAX; i++)
{
for(j = 0; j < MAX; j++)
{
if(_Weight[i][j].WEIGHT > _Weight[i][k].WEIGHT + _Weight[k][j].WEIGHT) //是否是最短路径
{
_Weight[i][j].WEIGHT = _Weight[i][k].WEIGHT + _Weight[k][j].WEIGHT;
Path[i][j].WEIGHT = k;
}
}
}
}
Dispath(MG, _Weight, Path, Start, End);
}
void Ppath(MGraph MG, View Path[][MAX], int i, int j)
{
int k;
k = Path[i][j].WEIGHT;
if(k == -1)
{
return;
}
Ppath(MG, Path, i, k);
printf("%s->", MG.Vertex[k].NAME);
Ppath(MG, Path, k, j);
}
void Dispath(MGraph MG, View _Weight[][MAX], View Path[][MAX], int Start, int End)
{
int i, j;
for(i = 0; i < MAX; i++)
{
for(j = 0; j < MAX; j++)
{
if(_Weight[i][j].WEIGHT == INF)
{
if(i != j)
{
printf("从%s到%s没有路径\n",MG.Vertex[i].NAME, MG.Vertex[j].NAME);
}
}
if(i == Start && j == End)
{
printf("\n>>>>从[%s]=>[%s]的最短路径长度为:%d\n\n最短路径为\n",MG.Vertex[i].NAME, MG.Vertex[j].NAME, _Weight[i][j]);
printf(">>>>%s->", MG.Vertex[i].NAME);
Ppath(MG, Path, i, j);
printf("%s\n\n", MG.Vertex[j].NAME);
}
}
}
}
void One_Two(MGraph MG)
{
int Start, End, Value;
printf("请输入一个起始点编号: ");
Value = scanf("%d", &Start);
while((Start < 1 || Start > 16) || Value == 0)
{
while(getchar() != ‘\n‘){}
printf("\n>>>输入起始点编号错误!请重新输入!\n\n");
printf("请输入一个起始点编号: ");
Value = scanf("%d", &Start);
}
printf("请输入一个目的地编号: ");
Value = scanf("%d", &End);
while((End < 1 || End > 16) || Value == 0)
{
while(getchar() != ‘\n‘){}
printf("\n>>>输入目的地编号错误!请重新输入!\n");
printf("请输入一个目的地编号: ");
Value = scanf("%d", &End);
}
Floyd(MG, Start-1, End-1);
}
void MENU(MGraph MG)
{
int i, n = 1;
printf("\n");
printf("\t**********************************************\n");
printf("\t&&&&&& 南阳理工校园导航 &&&&&&\n");
printf("\t**********************************************\n");
for(i = 0; i < MAX; i++)
{
if(i == 0)
{
printf("\t[%d]%s\t", i+1, MG.Vertex[i].NAME);
n++;
}
else
{
printf("[%d]%s\t", i+1, MG.Vertex[i].NAME);
if(n % 3 == 0)
printf("\n\t");
n++;
}
}
printf("\n\t**********************************************\n");
printf("\t**********************************************\n\n");
printf("\t\t[1]查询任意两点之间的距离\n");
printf("\t\t[0]退出\n\n");
}
int main()
{
MGraph MG;
CreateMGraph(&MG);
while(1)
{
int Value, n = 3;
MENU(MG);
printf(">>>请选择: ");
Value = scanf("%d", &n);
if(Value == 0)
{
while(getchar() != ‘\n‘){}
}
switch(n)
{
case 1: One_Two(MG);break;
case 0: exit(0);
default: printf("输入错误!请重新输入!\n");
}
}
return 0;
}