用数据结构迪杰斯特拉写一个学校校园路径导航
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define MAX_VERTEX 20
#define INFINITY 65535
void displayAllSpotGuide(){
printf("******欢迎使用川大锦城导航图(部分)系统 Bata.1********\n");
printf(" \n");
printf(" |---------------------3.四维大楼 \n");
printf(" | | \n");
printf(" | | \n");
printf(" 15.图书馆------14.苹果湖---------------------1.北门 \n");
printf(" | | | | \n");
printf(" | | | | \n");
printf(" | | | | \n");
printf(" | 13.信义大楼----------4.和平大楼 | \n");
printf(" | | \n");
printf(" 16.学生农场------12.仁爱大楼----------5.六食堂-------| \n");
printf(" | | | \n");
printf(" | | | \n");
printf(" | | | \n");
printf(" 17.四五食堂------11.忠孝大楼------6.一二三食堂---2.南门 \n");
printf(" | | | | \n");
printf(" | | | | \n");
printf(" | | | | \n");
printf(" |********|-------10.校医院---------|********| | \n");
printf(" |西区宿舍| | |东区宿舍| | \n");
printf(" | 18. | | | 7. | | \n");
printf(" | | | | | | \n");
printf(" | |-------9.小吃街----------| | | \n");
printf(" | | | | | | \n");
printf(" |********| | |********| \n");
printf(" | \n");
printf(" 8.停车场 \n");
printf("*********************制作人:杨文涛************************\n");
printf("*****此版本正处于开发阶段,部分功能暂未完善,不能使用******\n");
}
typedef char Arr[100];
typedef int Patharc[MAX_VERTEX];//用于存储最短路径下标的数组
typedef int ShortPathTable[MAX_VERTEX];//用于存储到各点最短路径的权值和
Arr arr[MAX_VERTEX]={
"北门","南门","四维大楼","和平大楼","六食堂","一二三食堂","东区宿舍","停车场","小吃街","校医院","忠孝大楼","仁爱大楼","信义大楼","苹果胡","图书馆","学生农场","四五食堂","西区宿舍"
};
Arr arr2[MAX_VERTEX]={
"出入学校的必经之路","学校老门","最新的教学楼,集齐了各种高科技功能实验室","学校行政大楼","学生第六食堂,钵钵鸡和螺蛳粉很好吃","三层食堂,每层都有好吃的,很受学生欢迎",
"学校东区宿舍楼,学生休息的地方","学校的外层停车场,在东13后面","学校除食堂外的一个小吃街,有很多美食","学校中的医院,学生生病什么的都在这里看病","教学楼A教","教学楼B教",
"教学楼C教","学校最大的一个湖,里面有黑天鹅和鲤鱼","同学们自习的地方,藏书多,环境好,有空调","锦城特色农场劳动课上课地点,种菜锄地","学校四五食堂,也有很多好吃的","学校西区宿舍"
};
typedef struct{
int number;// 第几个顶点
char *spotInformation;//顶点的介绍信息
char *sight;//顶点的名称
}VertexType;//顶点的信息
typedef struct {
VertexType vex[MAX_VERTEX];//用来存储顶点信息
int arcs[MAX_VERTEX][MAX_VERTEX];//邻接矩阵用来存储图
int vexnum;//图中顶点的个数
int edgnum;//图中边的个数
}LGraph;//图存储的声明
void initializeArray(LGraph *H,int x,int y,int num){
//存在一条路径即在矩阵中存储时需要进行两次赋值
H->edgnum++;
H->arcs[x-1][y-1] = num;
H->arcs[y-1][x-1] = num;
}
void createLGraph(LGraph *H){
int i,j;
H->vexnum=18;//顶点的个数为17
//因为我用另个数组分别存储了顶点的名称和顶点的介绍,
//所以我需要循环为VertexType vex[MAX_VERTEX]中的信息赋值
for(i=0;i<18;i++){
//因为我的spotInformation为一个指针,我把spotInformation指向了arr2相应的位置
H->vex[i].spotInformation=arr2[i];
//sight也指向了arr中相应的信息的位置
H->vex[i].sight = arr[i];
H->vex[i].number = i;
}
for(j=0;j<H->vexnum;j++){
for(i=0;i<H->vexnum;i++){
H->arcs[j][i]=INFINITY;//循环先将矩阵各个点的值赋值为INFINITY,即都没有路径
}
}
//此时再把有路径的进行赋值,initializeArray()函数是实现路径互通
initializeArray(H,1,2,150);
initializeArray(H,1,3,40);
initializeArray(H,1,4,60);
initializeArray(H,1,14,80);
initializeArray(H,1,7,722);
initializeArray(H,2,6,80);
initializeArray(H,2,5,100);
initializeArray(H,3,14,90);
initializeArray(H,4,5,30);
initializeArray(H,4,13,40);
initializeArray(H,4,14,35);
initializeArray(H,5,12,30);
initializeArray(H,5,13,30);
initializeArray(H,6,11,25);
initializeArray(H,6,7,40);
initializeArray(H,7,9,50);
initializeArray(H,7,10,60);
initializeArray(H,8,9,40);
initializeArray(H,9,18,50);
initializeArray(H,10,18,60);
initializeArray(H,10,11,30);
initializeArray(H,11,17,40);
initializeArray(H,11,12,30);
initializeArray(H,12,13,30);
initializeArray(H,12,16,45);
initializeArray(H,13,14,25);
initializeArray(H,14,15,40);
initializeArray(H,15,16,50);
initializeArray(H,16,17,45);
initializeArray(H,17,18,35);
}
void shortPath(LGraph *H,int v0,Patharc *P,ShortPathTable *D){
int v,w,k,min;
int final[MAX_VERTEX];//final[w]=1表示求得顶点v0到vw的最短路径
// 初始化数据
for(v=0;v<H->vexnum;v++){
final[v]=0;//全部顶点初始化为未知最短路径状态
(*D)[v]=H->arcs[v0][v];//将与v0点有连线的顶点加上权值
(*P)[v]=0;
}
(*D)[v0] = 0;//v0至v0的路径为0
final[v0] = 1;
//开始主循环,每次求得v0到某个顶点的最短路径
for(v=1;v<H->vexnum;v++){
min = INFINITY;//当前所知离v0顶点的最近距离
for(w=0;w<H->vexnum;w++){
if(!final[w]&&(*D)[w]<min){//final[w]=1表示从v0到w的最短路径已经求得
k=w;//k存储此时最小值的下标
min = (*D)[w];//min最if条件语句执行后为最小
}
}
final[k]=1;//将目前找到的最经的顶点置为1
//修正当前最短路径及距离
for(w=0;w<H->vexnum;w++){
//如果经过v顶点的路径比现在这条路径的长度短的话
if(!final[w]&&(min+H->arcs[k][w]<(*D)[w])){
//说明找到了更短的路径,修改D[w]和P[w]
(*D)[w] = min+H->arcs[k][w];//修改当前路径长度
(*P)[w] = k;
}
}
}
}
void displayTwoPonitShortest(LGraph *H){
int position1,position2,j=0,i=0,temp;
int arr[MAX_VERTEX];
Patharc P;//最短路径的下标
ShortPathTable D;//到某顶点的最短路径的权值
printf("请输入你要查询的两个景点的序列号\n");
scanf("%d%d",&position1,&position2);
shortPath(H,position1-1,&P,&D);
arr[0]=position2-1;
j = position2-1;
while(P[j]!=0){
arr[i]=P[j];
i++;
j=P[j];
}
printf("从%s到%s的最短路径为:\n",H->vex[position1-1].sight,H->vex[position2-1].sight);
printf("%s -> ",H->vex[position1-1].sight);
for(int t=i-1;t>=0;t--){
printf("%s -> ",H->vex[arr[t]].sight);
}
printf("%s",H->vex[position2-1].sight);
}
void Information(LGraph *H){
for(int i=0;i<H->vexnum;i++){
printf("%d %s : %s\n",H->vex[i].number+1,H->vex[i].sight,H->vex[i].spotInformation);
}
}
void user(LGraph *H){
int select;
displayAllSpotGuide();
while(true){
printf("\n");
printf("\n");
printf("\n");
printf("1.景点信息查询\n");
printf("2.查询景点的最短路径\n");
printf("3.显示校园导图\n");
printf("4.返回\n");
printf("0.退出\n");
scanf("%d",&select);
switch(select){
case 1:
Information(H);break;
case 2:
displayTwoPonitShortest(H);break;
case 3:
displayAllSpotGuide();break;
case 4:
return;
case 0:
exit(1);
break;
default:
printf("你输入了错误的选项\n");
}
}
}
int main()
{
LGraph *H=(LGraph*)malloc(sizeof(LGraph));
createLGraph(H);
int select;
while(true){
displayAllSpotGuide();
printf("1.进入系统\n");
printf("2.推出系统\n");
scanf("%d",&select);
switch(select){
case 1:
user(H);
break;
case 2:
exit(1);
break;
default:
printf("你输入了错误的选项\n");
}
}
return 0;
}