数据结构导航系统

#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;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值