/***********************************************************
*版权所有 (c)2017,yuchen
*文件名称:school guiade create
*文件标识:无
*内容:该代码是用于校园导游,引导游客参观校园
*其他说明:用到了图为主要结构
*作者:于琛
*完成日期:20171221
*修改记录:无
**********************************************************/
//graph.h
#include <stdio.h>
#define MAXV 100//图的最大定点个数
#define INF 100000//无穷大
#define NS 14 //目前景点个数
typedef struct
{
char name[20];//景点名字
char num[10];//景点代号
char in[300];//景点介绍及其功能
}VertexType;
typedef struct
{
int n; //景点编号
VertexType odate; //景点信息
}View;//带编号的景点
typedef struct
{
int edges[MAXV][MAXV];//邻接矩阵存放的是路径长度
int v,e;//定点数边数
View vexs[MAXV];//景点数组
}MatGraph;
void createMat(MatGraph &MGr);//创建图
void introduce(MatGraph MGr);//景点介绍
void Ppath(int path[],int i,int vs);
void Dispath(int dist[],int path[],int s[],int v,int vs);
void Djst(MatGraph MGr,int v);//迪杰斯特拉
void Djp(int &vnum,MatGraph &MGr);//dj判别
void Dispath1(int A[][MAXV],int path[][MAXV],int v);
void Ppath1(int path[][MAXV],int i,int j);
void Floyd(MatGraph MGr);//弗罗伊德
void addviewsp(int &a,MatGraph &MGr);//添加顶点判别
void addedges(MatGraph &MGr);//添加边
void map();//地图
void change(MatGraph &MGr);//改变节点信息
void DFS(MatGraph &MGr, int i,int visited[]);
void DFSTraverse(MatGraph &MGr,int visited[]);//深度优先遍历
void deleteedge(MatGraph &MGr);//删除边
void addedges2(MatGraph &MGr,int i);//加结点后加边
//graph.cpp
#include <stdio.h>
#include <string.h>
#include "graph.h"
/*********************************************************
*功能:初始化图,增加14个节点
*输入参数:&MGr图结构体变量
*输出:MGr初始化后
*返回值:void
*其他说明:初始化建立一个14个节点的图
**********************************************************/
void createMat(MatGraph &MGr)//全局图结构体,创建矩阵并初始化
{
int i,j;
for(i=0;i<NS;i++)
{
for(j=0;j<NS;j++)
{
MGr.edges[i][j]=INF;
}
}
MGr.vexs[0].n=0;
strcpy(MGr.vexs[0].odate.name,"学校南门门");
strcpy(MGr.vexs[0].odate.num,"000");
strcpy(MGr.vexs[0].odate.in,"坐落于银海路,交通发达");
MGr.vexs[1].n=1;
strcpy(MGr.vexs[1].odate.name,"综合楼");
strcpy(MGr.vexs[1].odate.num,"001");
strcpy(MGr.vexs[1].odate.in,"里面有多个教室,是学习自习的好地方");
MGr.vexs[2].n=2;
strcpy(MGr.vexs[2].odate.name,"图书馆");
strcpy(MGr.vexs[2].odate.num,"002");
strcpy(MGr.vexs[2].odate.in,"藏有大量书籍,是安静学习的");
MGr.vexs[3].n=3;
strcpy(MGr.vexs[3].odate.name,"烟台大学第七餐厅");
strcpy(MGr.vexs[3].odate.num,"003");
strcpy(MGr.vexs[3].odate.in,"传称亚洲最大食堂,共四层内有许多好吃的,还有台球厅");
MGr.vexs[4].n=4;
strcpy(MGr.vexs[4].odate.name,"足球场");
strcpy(MGr.vexs[4].odate.num,"004");
strcpy(MGr.vexs[4].odate.in,"青青草原");
MGr.vexs[5].n=5;
strcpy(MGr.vexs[5].odate.name,"三元湖");
strcpy(MGr.vexs[5].odate.num,"005");
strcpy(MGr.vexs[5].odate.in,"内有荷花荷叶,烟大最美的地方美不胜收");
MGr.vexs[6].n=6;
strcpy(MGr.vexs[6].odate.name,"四五七教学楼");
strcpy(MGr.vexs[6].odate.num,"006");
strcpy(MGr.vexs[6].odate.in,"上专业课的地方,充满专业气息");
MGr.vexs[7].n=7;
strcpy(MGr.vexs[7].odate.name,"钟楼");
strcpy(MGr.vexs[7].odate.num,"007");
strcpy(MGr.vexs[7].odate.in,"又叫科技馆,学习计算机知识的好地方");
MGr.vexs[8].n=8;
strcpy(MGr.vexs[8].odate.name,"一二三教学楼和餐厅");
strcpy(MGr.vexs[8].odate.num,"008");
strcpy(MGr.vexs[8].odate.in,"考研胜地,每到早晨书声朗朗,还有好吃的食堂");
MGr.vexs[9].n=9;
strcpy(MGr.vexs[9].odate.name,"西南门");
strcpy(MGr.vexs[9].odate.num,"009");
strcpy(MGr.vexs[9].odate.in,"坐落于烟大路,路口属丁字路口,交通四通八达,对面还有新世界大型商场");
MGr.vexs[10].n=10;
strcpy(MGr.vexs[10].odate.name,"学校东门");
strcpy(MGr.vexs[10].odate.num,"010");
strcpy(MGr.vexs[10].odate.in,"位于海边,海景会让你美不胜收");
MGr.vexs[11].n=11;
strcpy(MGr.vexs[11].odate.name,"家属楼");
strcpy(MGr.vexs[11].odate.num,"011");
strcpy(MGr.vexs[11].odate.in,"教师学生生活的地方,还有老年活动中心和体育场");
MGr.vexs[12].n=12;
strcpy(MGr.vexs[12].odate.name,"校医院");
strcpy(MGr.vexs[12].odate.num,"012");
strcpy(MGr.vexs[12].odate.in,"学生生病看病的好地方");
MGr.vexs[13].n=13;
strcpy(MGr.vexs[13].odate.name,"学生公寓");
strcpy(MGr.vexs[13].odate.num,"013");
strcpy(MGr.vexs[13].odate.in,"学生休息的地方");
MGr.v=14;
MGr.edges[0][1]=MGr.edges[1][0]=50;
MGr.edges[0][5]=MGr.edges[5][0]=150;
MGr.edges[0][8]=MGr.edges[8][0]=300;
MGr.edges[1][2]=MGr.edges[2][1]=50;
MGr.edges[2][3]=MGr.edges[3][2]=70;
MGr.edges[1][4]=MGr.edges[4][1]=70;
MGr.edges[2][4]=MGr.edges[4][2]=60;
MGr.edges[4][5]=MGr.edges[5][4]=100;
MGr.edges[3][7]=MGr.edges[7][3]=100;
MGr.edges[5][6]=MGr.edges[6][5]=200;
MGr.edges[5][8]=MGr.edges[8][5]=300;
MGr.edges[6][7]=MGr.edges[7][6]=400;
MGr.edges[7][8]=MGr.edges[8][7]=100;
MGr.edges[7][9]=MGr.edges[9][7]=150;
MGr.edges[8][10]=MGr.edges[10][8]=50;
MGr.edges[9][10]=MGr.edges[10][9]=500;
MGr.edges[10][11]=MGr.edges[11][10]=400;
MGr.edges[11][12]=MGr.edges[12][11]=50;
MGr.edges[12][13]=MGr.edges[13][12]=20;
MGr.edges[10][13]=MGr.edges[13][10]=80;
MGr.e=20;
MGr.edges[0][0]=MGr.edges[1][1]=MGr.edges[2][2]=MGr.edges[3][3]=0;
MGr.edges[4][4]=MGr.edges[5][5]=MGr.edges[6][6]=MGr.edges[7][7]=0;
MGr.edges[8][8]=MGr.edges[9][9]=MGr.edges[10][10]=MGr.edges[11][11]=0;
MGr.edges[12][12]=MGr.edges[13][13]=0;
}
/*********************************************************
*功能:查询节点
*输入参数:MGr
*输出:查询节点信息
*返回值:void
*其他说明:无
**********************************************************/
void introduce(MatGraph MGr)
{
int m;
int i;
printf("请输入查询景点编号:\n");
scanf("%d",&m);
fflush(stdin);//清除缓存,清楚界面
for(i=0;i<MGr.v;i++)
{
if(i==m)
{
printf("景点代号:%s\t",MGr.vexs[i].odate.num);
printf("景点名称:%s\n",MGr.vexs[i].odate.name);
printf("景点简介:%s\n",MGr.vexs[i].odate.in);
break;
}
}
if(i>=MGr.v)
{
printf("输入序号错误。\n");
}
printf("\n");
}
/*********************************************************
*功能:迪杰斯特拉的一步,递归查找路径
*输入参数:path[],int i,vs
*输出:顶点
*返回值:void
*其他说明:无
**********************************************************/
void Ppath(int path[],int i,int vs) //前向递归查找路径上的顶点
{
int k;
k=path[i];
if (k==vs) return; //找到了起点则返回
Ppath(path,k,vs); //找顶点k的前一个顶点
printf("%d->",k); //输出顶点k
}
/*********************************************************
*功能:迪杰斯特拉的一步,输出路径
*输入参数:dist[],path[],s[],v,vs分别为距离,是否有路径,辅助数组是否为最短路径,起点,终点
*输出:路径
*返回值:void
*其他说明:无
**********************************************************/
void Dispath(int dist[],int path[],int s[],int v,int vs)//vs输入的顶点号
{
int i;
for (i=0;i<v;i++)
if (s[i]==1)
{
printf(" 从%d到%d的最短路径长度为:%d\t路径为:",vs,i,dist[i]);
if(i==vs)
{
printf("%d->%d\n",vs,i);
}
else
{
printf("%d->",vs); //输出路径上的起点
Ppath(path,i,vs); //输出路径上的中间点
printf("%d\n",i); //输出路径上的终点
}
}
else if(dist[i]==INF)
{
printf(" 从%d到%d不存在路径\n",vs,i);
}
else
printf(" 从%d到%d不存在路径\n",vs,i);
}
/*********************************************************
*功能:迪杰斯特拉的核心,dp
*输入参数:MGr,vs图结构体变量,起点
*输出:无
*返回值:void
*其他说明:查找最短路径遍历访问判别
**********************************************************/
void Djst(MatGraph MGr,int vs)
{
int dist[MAXV],path[MAXV];
int s[MAXV];
int mindis,i,j,u;
for (i=0; i<MGr.v; i++)
{
dist[i]=MGr.edges[vs][i]; //距离初始化
s[i]=0; //s[]置空
if (MGr.edges[vs][i]<INF) //路径初始化
path[i]=vs;
else
path[i]=-1;
}
s[vs]=1;
path[vs]=0; //源点编号vs放入s中
for (i=0; i<MGr.v; i++) //循环直到所有顶点的最短路径都求出change
{
mindis=INF; //mindis置最小长度初值
for (j=0; j<MGr.v; j++) //选取不在s中且具有最小距离的顶点u
if (s[j]==0 && dist[j]<mindis)
{
u=j;
mindis=dist[j];
}
s[u]=1; //顶点u加入s中
for (j=0; j<MGr.v; j++) //修改不在s中的顶点的距离
if (s[j]==0)
if (MGr.edges[u][j]<INF && dist[u]+MGr.edges[u][j]<dist[j])
{
dist[j]=dist[u]+MGr.edges[u][j];
path[j]=u;
}
}
Dispath(dist,path,s,MGr.v,vs); //输出最短路径
}
/*********************************************************
*功能:Flody的一步,递归查找
*输入参数:path[][MAXV],i,j//路径长度数组,起点,终点
*输出:无
*返回值:void
*其他说明:无
**********************************************************/
void Ppath1(int path[][MAXV],int i,int j) //前向递归查找路径上的顶点
{
int k;
k=path[i][j];
if (k==-1) return; //找到了起点则返回
Ppath1(path,i,k); //找顶点i的前一个顶点k
printf("%d->",k);
Ppath1(path,k,j); //找顶点k的前一个顶点j
}
/*********************************************************
*功能:Flody的一步,输出
*输入参数:A[][MAXV],path[][MAXV],v 存储图矩阵,最短路径
*输出:路径
*返回值:void
*其他说明:无
**********************************************************/
void Dispath1(int A[][MAXV],int path[][MAXV],int v)
{
int i,j;
for (i=0; i<v; i++)
for (j=0; j<v; j++)
{
if (A[i][j]==INF)
{
if (i!=j)
printf(" 从%d到%d没有路径\n",i,j);
}
else
{
printf(" 从%d到%d=>路径长度:%d 路径:",i,j,A[i][j]);
printf("%d->",i); //输出路径上的起点
Ppath1(path,i,j); //输出路径上的中间点
printf("%d\n",j); //输出路径上的终点
}
}
}
/*********************************************************
*功能:Flody的一步,核心
*输入参数:MGr
*输出:无
*返回值:void
*其他说明:路径查询
**********************************************************/
void Floyd(MatGraph MGr)
{
int A[MAXV][MAXV],path[MAXV][MAXV];
int i,j,k;
for (i=0; i<MGr.v; i++)
for (j=0; j<MGr.v; j++)
{
A[i][j]=MGr.edges[i][j];
path[i][j]=-1;
}
for (k=0; k<MGr.v; k++)
{
for (i=0; i<MGr.v; i++)
for (j=0; j<MGr.v; j++)
if (A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
Dispath1(A,path,MGr.v); //输出最短路径
}
/*********************************************************
*功能:加边
*输入参数:MGr
*输出:MGr添加了边
*返回值:void
*其他说明:无
**********************************************************/
void addedges(MatGraph &MGr)
{
int i,j;
int d;
printf("请输入你要添加的边端点编号:\n");
scanf("%d",&i);
scanf("%d",&j);
if(i==j)//判别
{
printf("不能修改\n");
return;
}
if(MGr.edges[i][j]!=INF)//路径存在
{
printf("此路径(路径必须大于0)已存在正在进行修改边:\n");
scanf("%d",&d);
MGr.edges[i][j]=MGr.edges[j][i]=d;
}
if(MGr.edges[i][j]==INF )
{
printf("不存在建立边:\n");
scanf("%d",&d);
MGr.edges[i][j]=MGr.edges[j][i]=d;
MGr.e++;
}
fflush(stdin);
}
/*********************************************************
*功能:迪杰斯特拉输出判断
*输入参数:&vnum,&MGr
*输出:判断
*返回值:void
*其他说明:无
**********************************************************/
void Djp(int &vnum,MatGraph &MGr)//迪杰斯特拉输出判断
{
char a;
if(vnum>=MGr.v || vnum<0)
{
printf("无此节点请重新输入!");
fflush(stdin);
printf("是否重新输入?请输入y or n\n");
scanf("%c",&a);
if(a=='y')
{
printf("请输入你要查寻最短路径的起始点:");
scanf("%d",&vnum);
Djp(vnum,MGr);
}
if(a=='n')
{
fflush(stdin);
return;
}
}
else
{
fflush(stdin);
Djst(MGr,vnum);
}
}
/*********************************************************
*功能:添加节点
*输入参数: &a,&MGr输入的节点号,图的结构体变量
*输出:无
*返回值:void
*其他说明:无
**********************************************************/
void addviewsp(int &a,MatGraph &MGr)//添加节点
{
int i;
char b;
if(a<=MGr.v-1)//判断节点是否存在
{
fflush(stdin);
printf("此节点已存在,是否重新输入?请输入y or n\n");
scanf("%c",&b);
if(b=='y')
{
printf("请输入节点添加的节点编号:\n");
scanf("%d",&a);
addviewsp(a,MGr);
}
if(b=='n')
{
fflush(stdin);
return;
}
}
else
{
MGr.v++;//自增
printf("请输入景点名称:\n");//输入信息
scanf("%s",MGr.vexs[MGr.v-1].odate.name);
printf("请输入景点代号:\n");
scanf("%s",MGr.vexs[MGr.v-1].odate.num);
printf("请输入景点信息:\n");
scanf("%s",MGr.vexs[MGr.v-1].odate.in);
printf("添加完毕\n");
for(i=0;i<MGr.v-1;i++)
{
MGr.edges[MGr.v-1][i]=MGr.edges[i][MGr.v-1]=INF;
}
printf("请为此节点添加一个路径\n");
addedges2(MGr,MGr.v-1);
}
}
/*********************************************************
*功能:地图
*输入参数: 无
*输出:无
*返回值:void
*其他说明:无
**********************************************************/
void map()//地图节点
{
printf(" _____________________________________________________________________________\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ 11.家属楼 12.校医院 13.学生公寓 ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ 9.西门 10.东门 ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ 7.钟楼 8.一二三教 ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ 3.7餐 4.足球场 5.三元湖 6.四五七教 ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ ┃\n");
printf("┃ 2.图书馆 1.综合楼 ┃\n");
printf("┃ 0.南门 ┃\n");
printf("|_____________________________________________________________________________ |\n");
}
/*********************************************************
*功能:改景点信息
*输入参数:&MGr
*输出:改变后的节点信息
*返回值:void
*其他说明:无
**********************************************************/
void change(MatGraph &MGr)
{
int a;
printf("请输入你要更改的信息的代号:");
scanf("%d",&a);
if(a<=MGr.v-1)//输入改变的信息判断是否存在
{
printf("请输入修改的景点名:\n");
scanf("%s",MGr.vexs[a].odate.name);
printf("请输入修改的景点代号:\n");
scanf("%s",MGr.vexs[a].odate.num);
printf("请输入修改的景点信息:\n");
scanf("%s",MGr.vexs[a].odate.in);
}
if(a>MGr.v-1 || a<0)
{
printf("此节点不存在!\n");
}
}
/*********************************************************
*功能:深度优先,输出所有节点信息
*输入参数:&MGr, i,visited[]图结构体变量,输出的点,记录是否访问的数组
*输出:无
*返回值:void
*其他说明:递归
**********************************************************/
void DFS(MatGraph &MGr, int i,int visited[])//深度优先遍历
{
int j;
printf("景点代号:%s\t",MGr.vexs[i].odate.num);
printf("景点名称:%s\n",MGr.vexs[i].odate.name);
printf("景点简介:%s\n",MGr.vexs[i].odate.in);
visited[i] = 1;
for(j = 0; j < MGr.v; j++)
{
if(MGr.edges[i][j] != 0 && MGr.edges[i][j] != INF && !visited[j])
{
DFS(MGr,j,visited);//递归
}
}
}
void DFSTraverse(MatGraph &MGr,int visited[])
{
int i;
for(i = 0; i < MGr.v; i++)
{
visited[i] = 0;
}
for(i = 0; i < MGr.v; i++)
{
if(!visited[i])
{
DFS(MGr, i,visited);
}
}
}
/*********************************************************
*功能:删除边
*输入参数:&MGr
*输出:删除一条边
*返回值:void
*其他说明:无
**********************************************************/
void deleteedge(MatGraph &MGr)//删除边
{
int i,j;
printf("请输入你要删除的路径端点(删除后均连通):\n");
printf("请输入起点:\n");
scanf("%d",&i);
printf("请输入终点:\n");
scanf("%d",&j);
if(MGr.edges[i][j]!=INF)
{
if(i==j)
{
MGr.edges[i][j]=MGr.edges[j][i]=0;
printf("输入不合理!\n");
}
else
{
MGr.edges[i][j]=MGr.edges[j][i]=INF;
MGr.e--;
printf("删除路径成功!\n");
}
}
else
{
printf("无直接路径\n");
}
}
/*********************************************************
*功能:加边,在addviewsp调用
*输入参数:&MGr,i
*输出:为新节点添加了一条边
*返回值:void
*其他说明:无
**********************************************************/
void addedges2(MatGraph &MGr,int i)
{
int j;
int d;
printf("请输入你要添加的终点编号:\n");
scanf("%d",&j);
if(j>=MGr.v-1)
{
printf("此节点不存在或者是本身!请重新输入!");
addedges2(MGr,i);
}
else
{
printf("请输入距离:\n");
scanf("%d",&d);
MGr.edges[i][j]=MGr.edges[j][i]=d;//改变边的距离
}
fflush(stdin);
}
//main
#include <stdio.h>
#include "graph.h"
#include <stdlib.h>
#include <stdlib.h>
int main()
{
system("color 5f");
int vnum;
MatGraph MGr;
int visited[MAXV]={0};
int k;
int a;//添加景点
createMat(MGr);
printf("**********************************************************************\n");
printf("* _________________________________________________________________ *\n");
printf("* | |*\n");
printf("* | hello 欢迎使用烟台大学导游系统 hello |*\n");
printf("* | |*\n");
printf("* |_________________________________________________________________|*\n");
printf("**********************************************************************\n");//界面
printf("\n");
while(1)
{
printf("1.景点信息查询请按1键;\n");
printf("2.景点最短路径查询(每对顶点的最短路径弗洛伊德算法)请按2键;\n");
printf("3.景点最短路径查询(一个定点到所有定点的最短路径迪杰斯特拉算法)请按3键;\n");
printf("4.校内当前景点地图查询请按4键;\n");
printf("5.校内景点添加请按5键;\n");
printf("6.校内景点路线添加与修改请按6键;\n");
printf("7.修改景点信息请按7键;\n");
printf("8.输出所有景点点请按8键;\n");
printf("9.删除路径请按9键;\n");
printf("10.退出系统请按10键;\n");
printf("请选择: \n");
scanf("%d",&k);
switch(k)
{
case 1:printf("景点介绍查询\n");
introduce(MGr);
break;
case 2:printf("景点最短路径查询(佛洛依德算法)。\n");
Floyd(MGr);
break;
case 3:
printf("景点最短路径(迪杰斯特拉算法)查询。");
printf("请输入你要查寻最短路径的起始点:");
scanf("%d",&vnum);
Djp(vnum,MGr);
break;
case 4:
printf("景点地图:\n");
map();
fflush(stdin);
break;
case 5:
printf("请输入需要添加的将要建设的景点:\n");
printf("请输入景点编号:");
scanf("%d",&a);
addviewsp(a,MGr);
break;
case 6:
addedges(MGr);
break;
case 7:
change(MGr);
fflush(stdin);
break;
case 8:
DFSTraverse(MGr,visited);
break;
case 9:
deleteedge(MGr);
fflush(stdin);
break;
case 10:
printf("谢谢使用!\n");
exit(0);
}
}
system("pause");
return 0;
}
运行结果:
查找景点
flody
迪杰斯特拉
图
添加节点
添加或修改路径
修改节点信息
全部信息查找
删除路径