#include<stdio.h>//无向带权图
#include<stdlib.h>
#include<string.h>
#define Infinity 2000//表示无穷大
#define MaxVertexNum 20
#define MAX 40
#define key 10//key为顶点个数
typedef struct arcell//边的权值信息
{ int adj;//权值
}arcell,adjmatrix[MaxVertexNum][MaxVertexNum];//图的邻接矩阵类型
typedef struct vexsinfo//顶点信息
{ int position;//景点的编号
char name[32];//景点的名称
char introduction[256];//景点的介绍
char super_introduction[512];//景点的详细介绍
}vexsinfo;
typedef struct mgraph//图结构信息
{ vexsinfo vexs[MaxVertexNum];//顶点向量(数组)
adjmatrix arcs;//邻接矩阵
adjmatrix arcs1;//邻接矩阵
int vexnum,arcnum;//顶点数和边数
}mgraph;
//全局变量
mgraph campus; //图变量
int d[30];
int visited[30];
int shortest[MaxVertexNum][MaxVertexNum];//定义全局变量存储最小路径
int pathh[MaxVertexNum][MaxVertexNum];//定义存储路径
mgraph initgraph()
{ int i=0,j=0;
mgraph c;
c.vexnum=10;//顶点个数
c.arcnum=20;//边的个数
for(i=1;i<=key;i++)//依次设置顶点编号
c.vexs[i].position=i;
//依次输入顶点信息
strcpy(c.vexs[1].name,"1号教学楼");strcpy(c.vexs[1].super_introduction,"\n 第一栋教学楼 \n");
strcpy(c.vexs[1].introduction,"第一栋教学楼,方便同学们学习!");
strcpy(c.vexs[2].name,"2号教学楼");strcpy(c.vexs[2].super_introduction,"\n第二栋教学楼\n");
strcpy(c.vexs[2].introduction,"第二栋教学楼,方便同学们学习!");
strcpy(c.vexs[3].name,"3号教学楼");strcpy(c.vexs[3].super_introduction,"\n第三栋教学楼\n");
strcpy(c.vexs[3].introduction,"第三栋教学楼,方便同学们学习!");
strcpy(c.vexs[4].name,"图书馆");strcpy(c.vexs[4].super_introduction,"\n 各类藏书\n");
strcpy(c.vexs[4].introduction,"方便同学学习,看书,做作业。");
strcpy(c.vexs[5].name,"旧食堂");strcpy(c.vexs[5].super_introduction,"\n第一食堂\n");
strcpy(c.vexs[5].introduction,"有三层,有各类饭馆");
strcpy(c.vexs[6].name,"新食堂");strcpy(c.vexs[6].super_introduction,"\n第二食堂\n");
strcpy(c.vexs[6].introduction,"一层,有奶茶汉堡");
strcpy(c.vexs[7].name,"田径场");strcpy(c.vexs[7].super_introduction,"\n操场\n");
strcpy(c.vexs[7].introduction,"同学们锻炼上体育课的地方");
strcpy(c.vexs[8].name,"文体中心");strcpy(c.vexs[8].super_introduction,"\n室内场\n");
strcpy(c.vexs[8].introduction,"有室内羽毛球和篮球场,举办各种比赛");
strcpy(c.vexs[9].name,"超市");strcpy(c.vexs[9].super_introduction,"\n买日常用品 \n");
strcpy(c.vexs[9].introduction,"各种东西都有,方便同学们买各种生活用品");
strcpy(c.vexs[10].name,"医务室");strcpy(c.vexs[10].super_introduction,"\n 解决同学们健康问题\n");
strcpy(c.vexs[10].introduction,"给同学们治病,很便宜");
for(i=1;i<=key;i++)
for(j=1;j<=key;j++)
c.arcs[i][j].adj=Infinity;//先初始化图的邻接矩阵
c.arcs1[i][j].adj=Infinity;
c.arcs[1][2].adj=200;c.arcs[1][5].adj=470;c.arcs[2][3].adj=240;c.arcs[2][4].adj=400;c.arcs[3][4].adj=315;
c.arcs[3][9].adj=100;c.arcs[3][10].adj=300;c.arcs[4][5].adj=300;c.arcs[4][9].adj=200;c.arcs[5][6].adj=160;
c.arcs[5][7].adj=160;c.arcs[5][8].adj=230;c.arcs[5][9].adj=140;c.arcs[6][7].adj=100;c.arcs[7][8].adj=130;
c.arcs[8][9].adj=250;c.arcs[8][11].adj=200;c.arcs[9][10].adj=135;
c.arcs1[1][2].adj=100;c.arcs1[1][5].adj=170;c.arcs1[2][3].adj=140;c.arcs1[2][4].adj=300;c.arcs1[3][4].adj=215;
c.arcs1[3][9].adj=200;c.arcs1[3][10].adj=200;c.arcs1[4][5].adj=200;c.arcs1[4][9].adj=100;c.arcs1[5][6].adj=260;
c.arcs1[5][7].adj=120;c.arcs1[5][8].adj=130;c.arcs1[5][9].adj=340;c.arcs1[6][7].adj=300;c.arcs1[7][8].adj=330;
c.arcs1[8][9].adj=150;c.arcs1[8][11].adj=100;c.arcs1[9][10].adj=235;
for(i=1;i<=key;i++)//邻接矩阵是对称矩阵,对称赋值(无向图需要对称赋值)
for(j=1;j<=key;j++)
c.arcs[j][i].adj=c.arcs[i][j].adj;
c.arcs1[j][i].adj=c.arcs1[i][j].adj;
return c;
}
//2.查找景点在图中的序号
int locatevex(mgraph c,int v)//locatevex
{ int i;
for(i=1;i<=c.vexnum;i++)
if(v==c.vexs[i].position) return i;//找到,返回顶点序号i
return -1;//没有找到这个顶点
}
//菜单
void menu()
{
printf(" │ 欢迎来到 │\n");
printf(" │ 桂林信息科技学院 │\n");
printf(" │ 菜 单 选 择 │\n");
printf(" │ *************************************************** │\n");
printf(" │ * * │\n");
printf(" │ *************************************************** │\n");
printf(" │ * 1.学校景点介绍 ** * │\n");
printf(" │ *************************************************** │\n");
printf(" │ * 2.查询景点间最短路径 ** * │\n");//
printf(" │ *************************************************** │\n");
printf(" │ * 3.更改图信息 ** * │\n");
printf(" │ *************************************************** │\n");
printf(" │ * 0.退出 ** * │\n");
printf(" │ *************************************************** │\n");
}
//以下是修改图的相关信息。包括删除、增加结点和边
//8.增加一条边。返回值:1***
int enarc(mgraph *c)
{ int m,n,distance;
printf("\n请输入边的起点和终点编号,权值:");
scanf("%d %d %d",&m,&n,&distance);
while(m<0||m>c->vexnum||n<0||n>c->vexnum)
{ printf("输入错误,请重新输入:");
scanf("%d %d",&m,&n);
}
if(locatevex(campus,m)<0)
{ printf("此节点%d已删除",m);
return 1;
}
if(locatevex(campus,n)<0)
{ printf("此节点%d已被删除",n);
return 1;
}
c->arcs[m][n].adj=distance;//在邻接矩阵中多加一个值
c->arcs[n][m].adj=c->arcs[m][n].adj;
return 1;
}
//9.增加一个结点。返回值:1***
int envex(mgraph *c)
{ int i;
c->vexnum++;//顶点个数+1
printf("请输入您要增加结点的信息:");
printf("\n编号:");
scanf("%d",&c->vexs[c->vexnum].position);
printf("名称:");
scanf("%s",&c->vexs[c->vexnum].name);
printf("简介:");
scanf("%s",&c->vexs[c->vexnum].introduction);
printf("详细介绍:");
scanf("%s",&c->vexs[c->vexnum].super_introduction);
for(i=1;i<=c->vexnum;i++)
{ c->arcs[c->vexnum][i].adj=Infinity;
c->arcs[i][c->vexnum].adj=Infinity;
}
return 1;
}
//10.删除图的一个顶点。返回值:1***
int delvex(mgraph *c)
{ int i=0,j;
int m,v;
if(c->vexnum<=0)
{ printf("图中已无顶点");
return 1;
}
printf("\n下面请输入您要删除的景点编号:");
scanf("%d",&v);
while(v<0||v>key)
{ printf("\n输入错误!请重新输入:");
scanf("%d",&v);
}
m=locatevex(campus,v);
if(m<0)
{ printf("此顶点%d已删除\n",v);
return 1;
}
for(i=m;i<=c->vexnum-1;i++)
for(j=1;j<=c->vexnum;j++)//将二维数组中的第m+1行依次向前移动一行(删除第m行)
c->arcs[i][j]=c->arcs[i+1][j];
for(i=m;i<=c->vexnum-1;i++)
for(j=1;j<=c->vexnum;j++)//将二维数组中的第m+1列依次向前移动一列(删除第m列)
c->arcs[j][i]=c->arcs[j][i+1];
c->vexs[v].position=-1;//表示此点已删除,后期打印也不会显示该点
c->vexnum--;//顶点个数-1
return 1;
}
//11.删除图的一条边。返回值:1***
int delarc(mgraph *c)
{ int m,n,v0,v1;
if(c->vexnum<=0)
{ printf("图中已无边,无法删除。");
return 1;
}
printf("\n下面请输入您要删除的边的起点和终点编号:");
scanf("%d %d",&v0,&v1);
m=locatevex(campus,v0);
if(m<0)
{ printf("此%d顶点已删除",v0);
return 1;
}
n=locatevex(campus,v1);
if(n<0)
{ printf("此%d顶点已删除",v1);
return 1;
}
c->arcs[m][n].adj=Infinity;//将删掉的边的权值改为无穷
c->arcs[n][m].adj=Infinity;
c->arcnum --;//图中边数减1
return 1;
}
//12.输出图的邻接矩阵的值***
void printmatrix(mgraph c)
{ int i,j,k=0;
for(i=1;i<=key;i++)
{ if(c.vexs[i].position!=-1)
printf("%6d",i);//横着的标号1到11
}
printf("\n");
for(i=1;i<=c.vexnum;i++)
{ for(j=1;j<=c.vexnum;j++)
{ if(c.arcs[i][j].adj==Infinity)
printf(" *#@* ");
else
printf("%6d",c.arcs[i][j].adj);
k++;
if(k%c.vexnum==0) printf("\n");
}
}
}
//13.图的操作主调函数。返回值:1***
int changegraph(mgraph *c)
{ int yourchoice;
printf("(1)删除结点 (2)删除边\n");
printf("(3)增加结点 (4)增加边\n");
printf("(5)打印邻接矩阵 (0)返回上一级\n");
do
{ printf("请输入您的选择:");
scanf("%d",&yourchoice);
switch(yourchoice)
{
case 1:delvex(c);break;
case 2:delarc(c);break;
case 3:envex(c);break;
case 4:enarc(c);break;
case 5:printmatrix(campus);break;
case 0:system("cls");menu();return 1;//break;
default:printf("未找到该功能,请输入有效选项!\n");break;
}
}while(yourchoice);
}
int user_log()
{
changegraph(&campus);
}
//14.查询两景点间的最短路径(floyd算法)
void floyd(mgraph c)
{ int i,j,k;
for(i=1;i<=key;i++)//将图的邻接矩阵赋值给 shortest二维数组,将矩阵pathh全部初始化
{ for(j=1;j<=key;j++)
{ shortest[i][j]=c.arcs[i][j].adj;
pathh[i][j]=j; //如果i和j之间有弧,则将j 的前驱置为j
}
}
for(k=1;k<=key;k++)//完成以k为中间点对所有的顶点对(i,j)进行检测和修改
{ for(i=1;i<=key;i++)
{ for(j=1;j<=key;j++)
{
if(shortest[i][j]>shortest[i][k]+shortest[k][j])//从i到k到j的一条路径更新
{ shortest[i][j]=shortest[i][k]+shortest[k][j]; //更新shortest[i][j]
pathh[i][j]=pathh[i][k]; //更改j的前驱k
}
}
}
}
}
//打印出最短路径
void display(mgraph c,int i,int j)
{ int a,b;
a=i;b=j;
printf("您要查询的两景点间最短路径:\n\n");
printf("%d%s",a,c.vexs[a].name);
while(pathh[i][j]!=b)
{ printf("-->%d%s",pathh[i][j],c.vexs[pathh[i][j]].name);
i=pathh[i][j];
}
printf("-->%d%s\n\n",b,c.vexs[b].name);
printf("%s-->%s的最短路径是:%d 米。\n\n",c.vexs[a].name,c.vexs[b].name,shortest[a][b]);
}
void floyd_1(mgraph c)
{ int i,j,k;
for(i=1;i<=key;i++)//将图的邻接矩阵赋值给 shortest二维数组,将矩阵pathh全部初始化为-1
{ for(j=1;j<=key;j++)
{
pathh[i][j]=j;
}
}
for(k=1;k<=key;k++)//核心操作,完成了以k为中间点对所有的顶点对(i,j)进行检测和修改
{ for(i=1;i<=key;i++)
{ for(j=1;j<=key;j++)
{
if(shortest[i][j]>shortest[i][k]+shortest[k][j])
{ shortest[i][j]=shortest[i][k]+shortest[k][j];
pathh[i][j]=pathh[i][k];//记录一下所走的路 //P数组用来存放前驱顶点
}
}
}
}
}
//打印出最短路径
void display_1(mgraph c,int i,int j)
{ int a,b;
a=i;b=j;
printf("您要查询的两景点间最短路径:\n\n");
printf("%d%s",a,c.vexs[a].name);
while(pathh[i][j]!=b)
{ printf("-->%d%s",pathh[i][j],c.vexs[pathh[i][j]].name);
i=pathh[i][j];
}
printf("-->%d%s\n\n",b,c.vexs[b].name);
printf("%s-->%s的最短路径是:%d 米。\n\n",c.vexs[a].name,c.vexs[b].name,c.arcs1[i][j].adj);
}
//任意两点间最短距离(弗洛伊德算法)
int shortdistance(mgraph c)
{ int i,j;
int a;
printf("请输入要查询的两个景点的数字编号(1->10)中间用空格间隔开。\n");
scanf("%d %d",&i,&j);
if(i>key||i<0||j>key||j<0)
{ printf("输入信息错误!\n\n");
}
else
{
printf("1.步行\n ");
printf("2.骑车\n");
printf("请输入您的选择:");
scanf("%d",&a);
if(a==1){
floyd(c);
display(c,i,j);}
if(a==2)
{floyd_1(c);
display_1(c,i,j);
}
return 1;
}
}
//16.显示所有景点信息
void browsecompus(mgraph c)
{ int i;
printf(" \n\n编号 景点名称 简介\n");
printf("____________________________________________________________________________________________\n");
for(i=1;i<=key;i++)
{ if(c.vexs[i].position!=-1)
printf("%-10d%-25s%-80s\n",c.vexs[i].position,c.vexs[i].name,c.vexs[i].introduction);
}
printf("____________________________________________________________________________________________\n");
}
//18.主要工作函数。操作区用户界面
void mainwork()
{ menu();
int yourchoice;
campus=initgraph();
do
{ printf("请输入您的选择:");
scanf("%d",&yourchoice);
switch(yourchoice)
{
case 2:shortdistance(campus);break;
case 1:browsecompus(campus);break;
case 3:user_log();break;
case 0:printf("谢谢使用\n");break;
default:printf("未找到该功能,请输入有效选项!\n");break;
}
}while(yourchoice);
}
int main()
{
mainwork();
return 0;
}
数据结构导航系统
最新推荐文章于 2023-04-26 17:11:21 发布