前言 这是大二上学期刚学数据结构完成的课设项目,里面的功能还可以进一步的完善,仅供分享、参考、记录使用,加油!
设计目的 中国地大物博,文化底蕴颇深,旅游资源更是丰富多彩,也越来越流行“大学打卡热”,中国很多大学校园成为了游客们的打卡的“景区”,为了给来访西安邮电大学的游客更加方便、快捷的提供服务信息,以及为在校学生提供合适的行走路线,因此开发“西安邮电大学校园导航系统”给游客以及在校学生提供更好的服务。 本次课程设计的主题为校园导航系统,主要目的是使学生学习的理论知识与实际应用相结合,避免学生在“纸上谈兵”。亲历实际应用的设计过程,培养学生独立思考、处理具体问题的能力。理论是单一的,但实际应用问题是多变的,甚至是与理论相冲突的,如何满足实际问题的需求,处理好理论与应用的冲突,是每个学生都应该学会的。 对于“校园导航系统”的开发者,即学生本人来说,对其能力的提高主要分以下几点: ① 深化其脑海中对“图”这种数据的逻辑结构的认知; ② 要求学生熟练掌握“图”的邻接矩阵创建、邻接表创建; ③ 独立编写代码,提高学生逻辑思维能力; ④ 懂得运用几种最基本的“图”操作的算法。
设计内容 本系统功能全部划分给管理方和游客两种人群。 ①游客权限有:显示地图基本信息、查询某个地点的交通路线基本情况、查询两两地之间中转最少的路径、简单路径、最短路径等。 ②管理方登录后,除了使用用户的所有权限之外,还可以行使地图系统的高级权限,有:添加新顶点、添加新路线、撤销旧路线等。 下图为校园导航系统的平面图:
功能模块图
各功能函数描述 1)增加新地点 ①输入要增加的地点名称和地点信息,并且图的顶点数加1; ②修改flag文件中图的顶点数; ③可在introduce文件中查看新地点是否增加成功; ④实现了校园导航系统管理员增加新地点的功能。 2)增加新路线 ①输入要增加路线的起始地点、终止地点和路径的距离并且图的边数加1; ②修改flag文件中图的边数; ③可在adj文件中查看新路线是否增加成功; ④实现了校园导航系统管理员增加新路线的功能。 3)撤销旧路线 ①输入要撤销路线的起始地点和终止地点,并让其路径值为无穷,图的边数减1; ②修改flag文件中图的边数; ③可在adj文件中查看旧路线是否撤销成功; ④实现了校园导航系统管理员撤销旧路线的功能。 4)校园平面图 ①将校园平面图保存在map文件中; ②调用打印地图函数; ③实现了校园导航系统管理员和游客对校园平面图的查看。 5)地点信息查询 ①分三种查询方式:地点编号查询、地点名称查询、地点编号名称共同查询; ②当选择地点编号查询的时候,先打印出各地点名称对应的编号,然后输入要查询的地点的编号,即可显示出所查地点的信息; ③当选择地点名称查询的时候,输入需要查询的地点名称,如果有所要查询的地点名称 时,将显示出所查地点的信息; ④当选择地点编号名称共通查询的时候,先打印出各地点名称对应的编号,然后输入要查询的地点的编号和地点名称,即可显示出所要查询的地点的信息; ⑤实现了校园导航系统管理员和游客对地点信息的查询。 6)问路查询 ①分三种路线查询方式:两个地点之间所有的简单路径、两个地点之间中转最少的路径、两个地点之间最短路径; ②当查询两个地点之间所有的简单路径时,可以采用深度优先遍历,将所有路线打印出来; ③当查询两个地点之间中转最少的路径时,可以采用广度优先遍历,类似于树的按层次遍历,当起点遇到终点时,即为中转最少的路径,也可以采用深度优先遍历,记录中转的地点最少的那条路径输出; ④当查询两个地点之间的最短路径时,可以采用Dijkstra算法,借助两个辅助数组dist和path来查询最短路径; ⑤实现了校园导航系统管理员和游客对路线的查询。
各功能函数之间的调用关系
源代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#define MAXSIZE 66
#define MAXVEX 20
#define INFINITY 32767
int count1 = 0 ;
int way1[ MAXSIZE] = { 0 } ;
int count2 = 0 ;
int way2[ MAXSIZE] = { 0 } ;
int minc = MAXVEX;
int minway[ MAXSIZE] = { 0 } ;
typedef struct {
char name[ 19 ] ;
char info[ 66 ] ;
int visited;
} Vextype;
typedef struct {
int arcs[ MAXVEX] [ MAXVEX] ;
Vextype vex[ MAXVEX] ;
int vexnum;
int arcnum;
int visited[ MAXVEX] ;
} AdjMatrix;
void MapFile ( AdjMatrix G) {
char filename[ 30 ] = "map.txt" ;
FILE * fp;
fp = fopen ( filename, "wt" ) ;
if ( fp == NULL )
{
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
fprintf ( fp, "|------------------------------------------------------------------------------------------------|\n" ) ;
fprintf ( fp, "| ☆西安邮电大学校园地点一览 ☆ |\n" ) ;
fprintf ( fp, "|------------------------------------------------------------------------------------------------|\n" ) ;
fprintf ( fp, "| |\n" ) ;
fprintf ( fp, "| 西区正门 |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| | 东区正门==================逸夫楼 |\n" ) ;
fprintf ( fp, "| | | | |\n" ) ;
fprintf ( fp, "| |===水煮鸽子 | | |\n" ) ;
fprintf ( fp, "| | | | | |\n" ) ;
fprintf ( fp, "| 基础 | | 安美公寓 |\n" ) ;
fprintf ( fp, "| 教学楼 | | | |\n" ) ;
fprintf ( fp, "| | | | | |\n" ) ;
fprintf ( fp, "| | | | 安悦公寓 |\n" ) ;
fprintf ( fp, "| | | 东升苑 ====| |\n" ) ;
fprintf ( fp, "| | | | |\n" ) ;
fprintf ( fp, "| | 图书馆 | |\n" ) ;
fprintf ( fp, "| 教学实验楼 | | |\n" ) ;
fprintf ( fp, "| | |=====================================================| |\n" ) ;
fprintf ( fp, "| | | ||| 西邮桥 ||| | |\n" ) ;
fprintf ( fp, "| 医务室====| |=====================================================| |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| |===体育馆 |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| 旭日苑 |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| | |\n" ) ;
fprintf ( fp, "| 西区宿舍楼 |\n" ) ;
fprintf ( fp, "| |\n" ) ;
fprintf ( fp, "|------------------------------------------------------------------------------------------------|\n" ) ;
fclose ( fp) ;
}
void MapOutput ( ) {
printf ( "|------------------------------------------------------------------------------------------------|\n" ) ;
printf ( "| ☆西安邮电大学校园地点一览 ☆ |\n" ) ;
printf ( "|------------------------------------------------------------------------------------------------|\n" ) ;
printf ( "| |\n" ) ;
printf ( "| 西区正门 |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| | 东区正门==================逸夫楼 |\n" ) ;
printf ( "| | | | |\n" ) ;
printf ( "| |===水煮鸽子 | | |\n" ) ;
printf ( "| | | | | |\n" ) ;
printf ( "| 基础 | | 安美公寓 |\n" ) ;
printf ( "| 教学楼 | | | |\n" ) ;
printf ( "| | | | | |\n" ) ;
printf ( "| | | | 安悦公寓 |\n" ) ;
printf ( "| | | 东升苑 ====| |\n" ) ;
printf ( "| | | | |\n" ) ;
printf ( "| | 图书馆 | |\n" ) ;
printf ( "| 教学实验楼 | | |\n" ) ;
printf ( "| | |=====================================================| |\n" ) ;
printf ( "| | | ||| 西邮桥 ||| | |\n" ) ;
printf ( "| 医务室====| |=====================================================| |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| |===体育馆 |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| 旭日苑 |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| | |\n" ) ;
printf ( "| 西区宿舍楼 |\n" ) ;
printf ( "| |\n" ) ;
printf ( "|------------------------------------------------------------------------------------------------|\n" ) ;
}
void Create ( AdjMatrix * G) {
int i, j;
int m, n, weight;
int vexnum, arcnum;
char name[ 19 ] , info[ 66 ] ;
for ( i = 1 ; i <= G- > vexnum; i++ ) {
G- > vex[ i] . visited = 0 ;
}
FILE * fp1;
fp1 = fopen ( "flag.txt" , "rt" ) ;
if ( fp1 == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
FILE * fp2;
fp2 = fopen ( "introduce.txt" , "rt" ) ;
if ( fp2 == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
FILE * fp3;
fp3 = fopen ( "adj.txt" , "rt" ) ;
if ( fp3 == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
fscanf ( fp1, "%d %d" , & vexnum, & arcnum) ;
G- > vexnum = vexnum;
G- > arcnum = arcnum;
for ( i = 1 ; i <= G- > vexnum; i++ ) {
fscanf ( fp2, "%s\n%s" , name, info) ;
strcpy ( G- > vex[ i] . name, name) ;
strcpy ( G- > vex[ i] . info, info) ;
}
for ( i = 1 ; i <= G- > vexnum; i++ ) {
for ( j = 1 ; j <= G- > vexnum; j++ ) {
G- > arcs[ i] [ j] = INFINITY;
}
}
for ( j = 1 ; j <= G- > arcnum; j++ ) {
fscanf ( fp3, "%6d %6d %6d" , & m, & n, & weight) ;
G- > arcs[ m] [ n] = weight;
G- > arcs[ n] [ m] = weight;
}
fclose ( fp1) ;
fclose ( fp2) ;
fclose ( fp3) ;
}
void PrintPlace ( AdjMatrix * G) {
int i;
for ( i = 1 ; i <= G- > vexnum; i++ ) {
printf ( "\t\t\t\t\t\t%d\t%s\n" , i, G- > vex[ i] . name) ;
}
}
void IntroducePlace ( AdjMatrix G) {
int i, num, c;
int flag = 1 ;
char n[ 30 ] ;
while ( flag == 1 ) {
system ( "cls" ) ;
printf ( "\t\t\t\t\t\t——————地点信息查询——————\n" ) ;
printf ( "\t\t\t\t\t\t请选择需要查询的方式\n" ) ;
printf ( "\t\t\t\t\t\t1.地点编号查询\n" ) ;
printf ( "\t\t\t\t\t\t2.地点名称查询\n" ) ;
printf ( "\t\t\t\t\t\t3.地点编号名称共同查询\n" ) ;
scanf ( "%d" , & c) ;
if ( c == 1 ) {
system ( "cls" ) ;
PrintPlace ( & G) ;
printf ( "\t\t\t\t\t\t请输入需要查找的地点编号:" ) ;
scanf ( "%d" , & num ) ;
if ( num > 0 && num <= G. vexnum ) {
printf ( "\n\n" ) ;
printf ( "\t\t\t编号:%d\n" , num) ;
printf ( "\t\t\t名称:%s\n" , G. vex[ num] . name ) ;
printf ( "\t\t\t简介:%s\n\n" , G. vex[ num] . info ) ;
}
else {
printf ( "\t\t\t\t\t\t信息输入有误!\n" ) ;
}
printf ( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag ) ;
}
else if ( c == 2 ) {
system ( "cls" ) ;
printf ( "\t\t\t\t\t\t请输入需要查询的地点名称:" ) ;
scanf ( "%s" , n) ;
for ( i = 1 ; i <= G. vexnum; i++ ) {
if ( strcmp ( G. vex[ i] . name, n) == 0 ) {
printf ( "\n\n" ) ;
printf ( "\t\t\t编号:%d\n" , i) ;
printf ( "\t\t\t名称:%s\n" , G. vex[ i] . name ) ;
printf ( "\t\t\t简介:%s\n\n" , G. vex[ i] . info ) ;
break ;
}
}
printf ( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag ) ;
}
else if ( c == 3 ) {
system ( "cls" ) ;
PrintPlace ( & G) ;
printf ( "\t\t\t\t\t\t请输入需要查找的地点编号:" ) ;
scanf ( "%d" , & num ) ;
printf ( "\t\t\t\t\t\t请输入需要查询的地点名称:" ) ;
scanf ( "%s" , n) ;
if ( num > 0 && num <= G. vexnum && strcmp ( G. vex[ num] . name, n) == 0 ) {
printf ( "\n\n" ) ;
printf ( "\t\t\t编号:%d\n" , num) ;
printf ( "\t\t\t名称:%s\n" , G. vex[ num] . name ) ;
printf ( "\t\t\t简介:%s\n\n" , G. vex[ num] . info ) ;
}
printf ( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag ) ;
}
}
system ( "cls" ) ;
}
void IntroduceFile ( AdjMatrix G) {
int i;
char filename[ 30 ] = "introduce.txt" ;
FILE * fp;
fp = fopen ( filename, "wt" ) ;
if ( fp == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
G. vexnum = 15 ;
strcpy ( G. vex[ 1 ] . name, "西区正门" ) ;
strcpy ( G. vex[ 1 ] . info, "西安邮电大学长安校区西区的正门" ) ;
strcpy ( G. vex[ 2 ] . name, "西邮桥" ) ;
strcpy ( G. vex[ 2 ] . info, "链接西安邮电大学长安校区西区和东区的桥梁,过马路请走西游桥" ) ;
strcpy ( G. vex[ 3 ] . name, "东区正门" ) ;
strcpy ( G. vex[ 3 ] . info, "西安邮电大学长安校区东区的正门" ) ;
strcpy ( G. vex[ 4 ] . name, "水煮鸽子" ) ;
strcpy ( G. vex[ 4 ] . info, "西安邮电大学长安校区西区正门口,由鸽子和喷泉组成" ) ;
strcpy ( G. vex[ 5 ] . name, "基础教学楼" ) ;
strcpy ( G. vex[ 5 ] . info, "西安邮电大学教学楼,有A楼和B楼,是西安邮电大学学生们上课的地方" ) ;
strcpy ( G. vex[ 6 ] . name, "教学实验楼" ) ;
strcpy ( G. vex[ 6 ] . info, "西安邮电大学长安校区西区实验楼" ) ;
strcpy ( G. vex[ 7 ] . name, "逸夫楼" ) ;
strcpy ( G. vex[ 7 ] . info, "西安邮电大学教学楼,是学生们上课的地方,很容易迷路哦" ) ;
strcpy ( G. vex[ 8 ] . name, "图书馆" ) ;
strcpy ( G. vex[ 8 ] . info, "西安邮电大学图书馆,可以借阅书籍和自习" ) ;
strcpy ( G. vex[ 9 ] . name, "医务室" ) ;
strcpy ( G. vex[ 9 ] . info, "西安邮电大学医务室" ) ;
strcpy ( G. vex[ 10 ] . name, "旭日苑" ) ;
strcpy ( G. vex[ 10 ] . info, "西安邮电大学西区食堂" ) ;
strcpy ( G. vex[ 11 ] . name, "东升苑" ) ;
strcpy ( G. vex[ 11 ] . info, "西安邮电大学东区食堂" ) ;
strcpy ( G. vex[ 12 ] . name, "体育馆" ) ;
strcpy ( G. vex[ 12 ] . info, "西安邮电大学体育馆,内有运动场地" ) ;
strcpy ( G. vex[ 13 ] . name, "西区宿舍" ) ;
strcpy ( G. vex[ 13 ] . info, "分为长思公寓和长智公寓" ) ;
strcpy ( G. vex[ 14 ] . name, "安美公寓" ) ;
strcpy ( G. vex[ 14 ] . info, "分为安美公寓南楼和北楼" ) ;
strcpy ( G. vex[ 15 ] . name, "安悦公寓" ) ;
strcpy ( G. vex[ 15 ] . info, "分为安悦公寓南楼和北楼" ) ;
for ( i = 1 ; i <= G. vexnum; i++ ) {
fprintf ( fp, "%s\n%s\n" , G. vex[ i] . name, G. vex[ i] . info) ;
}
fclose ( fp) ;
}
void AdjFile ( AdjMatrix G) {
int i, j;
char filename[ 30 ] = "adj.txt" ;
char filename1[ 30 ] = "flag.txt" ;
FILE * fp;
fp = fopen ( filename, "wt" ) ;
if ( fp == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
FILE * fp1;
fp1 = fopen ( filename1, "wt" ) ;
if ( fp1 == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
G. vexnum = 15 ;
G. arcnum = 24 ;
fprintf ( fp1, "%d %d\n" , G. vexnum, G. arcnum) ;
for ( i = 0 ; i <= G. vexnum; i++ ) {
for ( j = 0 ; j <= G. vexnum; j++ ) {
G. arcs[ i] [ j] = INFINITY;
}
}
G. arcs[ 1 ] [ 3 ] = G. arcs[ 3 ] [ 1 ] = 800 ;
G. arcs[ 1 ] [ 4 ] = G. arcs[ 4 ] [ 1 ] = 120 ;
G. arcs[ 2 ] [ 3 ] = G. arcs[ 3 ] [ 2 ] = 300 ;
G. arcs[ 2 ] [ 8 ] = G. arcs[ 8 ] [ 2 ] = 450 ;
G. arcs[ 2 ] [ 9 ] = G. arcs[ 9 ] [ 2 ] = 600 ;
G. arcs[ 2 ] [ 11 ] = G. arcs[ 11 ] [ 2 ] = 100 ;
G. arcs[ 2 ] [ 12 ] = G. arcs[ 12 ] [ 2 ] = 500 ;
G. arcs[ 3 ] [ 7 ] = G. arcs[ 7 ] [ 3 ] = 150 ;
G. arcs[ 4 ] [ 5 ] = G. arcs[ 5 ] [ 4 ] = 140 ;
G. arcs[ 4 ] [ 8 ] = G. arcs[ 8 ] [ 4 ] = 200 ;
G. arcs[ 5 ] [ 6 ] = G. arcs[ 6 ] [ 5 ] = 111 ;
G. arcs[ 5 ] [ 8 ] = G. arcs[ 8 ] [ 5 ] = 222 ;
G. arcs[ 6 ] [ 8 ] = G. arcs[ 8 ] [ 6 ] = 300 ;
G. arcs[ 6 ] [ 9 ] = G. arcs[ 9 ] [ 6 ] = 417 ;
G. arcs[ 6 ] [ 10 ] = G. arcs[ 10 ] [ 6 ] = 360 ;
G. arcs[ 6 ] [ 12 ] = G. arcs[ 12 ] [ 6 ] = 250 ;
G. arcs[ 7 ] [ 14 ] = G. arcs[ 14 ] [ 7 ] = 120 ;
G. arcs[ 8 ] [ 12 ] = G. arcs[ 12 ] [ 8 ] = 345 ;
G. arcs[ 9 ] [ 10 ] = G. arcs[ 10 ] [ 9 ] = 404 ;
G. arcs[ 10 ] [ 12 ] = G. arcs[ 12 ] [ 10 ] = 200 ;
G. arcs[ 10 ] [ 13 ] = G. arcs[ 13 ] [ 10 ] = 100 ;
G. arcs[ 11 ] [ 15 ] = G. arcs[ 15 ] [ 11 ] = 150 ;
G. arcs[ 14 ] [ 15 ] = G. arcs[ 15 ] [ 14 ] = 50 ;
for ( i = 1 ; i <= G. vexnum; ++ i) {
for ( j = 1 ; j <= G. vexnum; ++ j) {
if ( G. arcs[ i] [ j] != INFINITY && i < j) {
fprintf ( fp, "%10d %10d %10d\n" , i, j, G. arcs[ i] [ j] ) ;
}
}
}
fclose ( fp1) ;
fclose ( fp) ;
}
void ClearVisited ( AdjMatrix * G) {
int i;
for ( i = 0 ; i <= MAXVEX; i++ ) {
G- > vex[ i] . visited = 0 ;
}
}
void DfsAll ( AdjMatrix * G, int s, int e) {
int i, j;
int shuai = 0 ;
G- > vex[ s] . visited = 1 ;
way1[ count1] = s;
for ( i = 1 ; i <= G- > vexnum; i++ ) {
if ( G- > arcs[ s] [ i] != INFINITY && G- > vex[ i] . visited == 0 && i != e) {
count1++ ;
way1[ count1] = i;
DfsAll ( G, i, e) ;
G- > vex[ i] . visited = 0 ;
count1-- ;
shuai = 0 ;
continue ;
}
if ( G- > arcs[ s] [ i] != INFINITY && G- > vex[ i] . visited == 0 && i == e && shuai == 0 ) {
count1++ ;
way1[ count1] = e;
shuai = 1 ;
printf ( "\n" ) ;
printf ( "\t%s" , G- > vex[ way1[ 0 ] ] . name) ;
for ( j = 1 ; j <= count1; j++ ) {
printf ( "-->" ) ;
printf ( "%s" , G- > vex[ way1[ j] ] . name) ;
}
count1-- ;
return ;
}
}
return ;
}
void AllPath ( AdjMatrix G, int dist[ ] , int path[ ] [ MAXVEX] ) {
int s, e;
int flag = 1 ;
while ( flag == 1 ) {
system ( "cls" ) ;
printf ( "\t\t\t\t\t\t——————所有简单路径查询——————\n" ) ;
PrintPlace ( & G) ;
printf ( "\n\t\t\t\t\t输入起点编号:" ) ;
scanf ( "%d" , & s) ;
printf ( "\t\t\t\t\t输入终点编号:" ) ;
scanf ( "%d" , & e) ;
if ( s > G. vexnum || s <= 0 || e > G. vexnum || e < 0 || s == e) {
printf ( "\t\t\t\t\t\t输入错误!\n\n" ) ;
}
else {
ClearVisited ( & G) ;
count1= 0 ;
printf ( "\n\t\t\t从%s到%s的所有简单路径有:\n" , G. vex[ s] . name, G. vex[ e] . name) ;
DfsAll ( & G, s, e) ;
}
printf ( "\n\n\t\t\t\t\t\t是否继续查询所有简单路径?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag) ;
}
system ( "cls" ) ;
}
void DfsLitter ( AdjMatrix * G, int start, int end) {
int shuai = 0 ;
int i, j;
G- > vex[ start] . visited = 1 ;
way2[ count2] = start;
for ( i = 1 ; i <= G- > vexnum; i++ ) {
if ( G- > arcs[ start] [ i] != INFINITY && G- > vex[ i] . visited == 0 && i != end) {
count2++ ;
way2[ count2] = i;
DfsLitter ( G, i, end) ;
G- > vex[ i] . visited = 0 ;
count2-- ;
shuai = 0 ;
continue ;
}
if ( G- > arcs[ start] [ i] != INFINITY && G- > vex[ i] . visited == 0 && i == end && shuai == 0 ) {
count2++ ;
way2[ count2] = end;
shuai = 1 ;
if ( count2 < minc) {
minc = count2;
for ( i = 0 ; i <= count2; i++ ) {
minway[ i] = way2[ i] ;
}
}
count2-- ;
return ;
}
}
}
void LitterPath ( AdjMatrix G) {
int i, j, s, e;
int flag = 1 ;
while ( flag == 1 ) {
int i;
system ( "cls" ) ;
printf ( "\t\t\t\t\t\t——————中转次数最少路径查询——————\n" ) ;
PrintPlace ( & G) ;
printf ( "\n\t\t\t\t\t输入起点编号:" ) ;
scanf ( "%d" , & s) ;
printf ( "\t\t\t\t\t输入终点编号:" ) ;
scanf ( "%d" , & e) ;
if ( s > G. vexnum || s <= 0 || e > G. vexnum || e < 0 || s == e)
printf ( "\t\t\t\t\t\t输入错误!\n\n" ) ;
else {
ClearVisited ( & G) ;
minc = MAXVEX;
count2 = 0 ;
printf ( "\n\t\t\t从%s到%s的中转最少简单路径为:\n" , G. vex[ s] . name, G. vex[ e] . name) ;
DfsLitter ( & G, s, e) ;
printf ( "\t\t\t%5s " , G. vex[ minway[ 0 ] ] . name) ;
for ( i = 1 ; i <= minc; i++ ) {
printf ( "-->" ) ;
printf ( "%5s " , G. vex[ minway[ i] ] . name) ;
}
printf ( "\n\n\t\t\t\t\t\t是否继续查询中转最少简单路径?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag) ;
}
system ( "cls" ) ;
}
}
void Dijkstra ( AdjMatrix * G, int s, int e, int dist[ MAXVEX] , int path[ ] [ MAXVEX] ) {
int mindist, i, j, k, t = 1 ;
for ( i = 1 ; i <= G- > vexnum; i++ ) {
dist[ i] = G- > arcs[ s] [ i] ;
if ( G- > arcs[ s] [ i] != INFINITY) {
path[ i] [ 1 ] = s;
}
}
path[ s] [ 0 ] = 1 ;
for ( i = 2 ; i <= G- > vexnum; i++ ) {
mindist = INFINITY;
for ( j = 1 ; j <= G- > vexnum; j++ ) {
if ( ! path[ j] [ 0 ] && dist[ j] < mindist) {
k = j;
mindist = dist[ j] ;
}
}
if ( mindist == INFINITY) {
return ;
}
path[ k] [ 0 ] = 1 ;
for ( j = 1 ; j <= G- > vexnum; j++ ) {
if ( ! path[ j] [ 0 ] && G- > arcs[ k] [ j] < INFINITY && dist[ k] + G- > arcs[ k] [ j] < dist[ j] ) {
dist[ j] = dist[ k] + G- > arcs[ k] [ j] ;
t = 1 ;
while ( path[ k] [ t] != 0 ) {
path[ j] [ t] = path[ k] [ t] ;
t++ ;
}
path[ j] [ t] = k;
path[ j] [ t+ 1 ] = 0 ;
}
}
}
}
void DijkstraPrint ( int start, int end , AdjMatrix G, int path[ ] [ MAXVEX] ) {
int i = 2 ;
int length = 0 ;
printf ( "\n\t从%s到%s的最短路径是:" , G. vex[ start] . name, G. vex[ end] . name ) ;
printf ( " %s" , G. vex[ start] . name ) ;
while ( path[ end] [ i] ) {
printf ( "-->%s " , G. vex[ path[ end] [ i] ] . name) ;
length + = G. arcs[ path[ end] [ i- 1 ] ] [ path[ end] [ i] ] ;
i++ ;
}
printf ( "-->%s" , G. vex[ end] . name ) ;
length + = G. arcs[ path[ end] [ i- 1 ] ] [ end] ;
printf ( ",长度为%dM" , length) ;
printf ( "\n" ) ;
}
void ShortPath ( AdjMatrix G, int dist[ ] , int path[ ] [ MAXVEX] ) {
int i, j, s, e;
int flag = 1 ;
while ( flag == 1 ) {
system ( "cls" ) ;
printf ( "\t\t\t\t\t\t——————最短路径查询——————\n" ) ;
PrintPlace ( & G) ;
printf ( "\n\t\t\t\t\t输入起点编号:" ) ;
scanf ( "%d" , & s) ;
printf ( "\t\t\t\t\t输入终点编号:" ) ;
scanf ( "%d" , & e) ;
if ( s > G. vexnum || s <= 0 || e > G. vexnum || e < 0 || s == e) {
printf ( "\t\t\t\t\t\t输入错误!\n\n" ) ;
}
else {
ClearVisited ( & G) ;
Dijkstra ( & G, s, e, dist, path) ;
DijkstraPrint ( s, e, G, path) ;
}
printf ( "\n\t\t\t\t\t\t是否继续查询最短路径?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag) ;
}
system ( "cls" ) ;
}
void SearchPath ( AdjMatrix G, int dist[ ] , int path[ ] [ MAXVEX] ) {
int x, flag = 1 ;
while ( flag == 1 ) {
printf ( "\t\t\t1. 所有简单路径\n" ) ;
printf ( "\t\t\t2. 最短的简单路径(中转最少)\n" ) ;
printf ( "\t\t\t3. 最佳访问路径(最短路径长度)\n" ) ;
printf ( "\t\t\t0. 返回主菜单\n" ) ;
printf ( "\t\t\t请选择您需要的操作:" ) ;
scanf ( "%d" , & x) ;
switch ( x) {
case 1 : system ( "cls" ) ; AllPath ( G, dist, path) ; break ;
case 2 : system ( "cls" ) ; LitterPath ( G) ; break ;
case 3 : system ( "cls" ) ; ShortPath ( G, dist, path) ; break ;
case 0 : flag = 0 ; break ;
default : printf ( "\t\t\t\t\t\t\t输入信息错误,请重新输入!\n" ) ; break ;
}
system ( "cls" ) ;
}
}
void enroll ( ) {
char a[ 100 ] ;
char b[ 100 ] ;
char s[ 100 ] ;
int len;
printf ( "请输入您的用户名:" ) ;
scanf ( "%s" , a) ;
printf ( "请设置您的密码:" ) ;
reset: scanf ( "%s" , b) ;
len = strlen ( b) ;
if ( len > 9 ) {
printf ( "密码长度过长,请重新设置:" ) ;
goto reset;
}
printf ( "请再次输入您设置的密码:" ) ;
scanf ( "%s" , s) ;
if ( strcmp ( b, s) == 0 ) {
FILE * fp;
fp= fopen ( "register.txt" , "at" ) ;
if ( fp == NULL ) {
printf ( "文件不存在或者请先注册!" ) ;
exit ( 1 ) ;
}
fprintf ( fp, "%s %s\n" , a, b) ;
system ( "cls" ) ;
printf ( "\n\t------注册成功------\n" ) ;
fclose ( fp) ;
}
else if ( strcmp ( b, s) != 0 ) {
printf ( "您两次输入的密码不一致,请重新设置密码!\n" ) ;
goto reset;
}
}
int land ( ) {
int i = 0 ;
char a[ 10 ] ;
char b[ 10 ] ;
char user_name[ 10 ] ;
char user_passwords[ 10 ] ;
printf ( "请输入您的用户名:" ) ;
scanf ( "%s" , user_name) ;
printf ( "请输入您的密码:" ) ;
while ( i < 9 && ( user_passwords[ i] = getch ( ) ) && user_passwords[ i] != '\r' ) {
printf ( "*" ) ;
i++ ;
}
user_passwords[ i] = 0 ;
FILE * fp;
fp= fopen ( "register.txt" , "rt" ) ;
if ( fp == NULL ) {
printf ( "文件不存在!" ) ;
exit ( 1 ) ;
}
while ( fscanf ( fp, "%s %s" , a, b) != EOF ) {
if ( strcmp ( a, user_name) == 0 && strcmp ( b, user_passwords) == 0 ) {
system ( "cls" ) ;
printf ( "\n\t\t\t--------登陆成功--------\n" ) ;
return 0 ;
}
}
if ( 1 ) {
system ( "cls" ) ;
printf ( "\n信息输入错误!(请检查注册文件信息)\n" ) ;
land ( ) ;
}
fclose ( fp) ;
}
void AddPlace ( AdjMatrix * G) {
int s, e;
char filename[ 30 ] = "introduce.txt" ;
char filename1[ 30 ] = "flag.txt" ;
int flag = 1 ;
char p[ 20 ] ;
char i[ 66 ] ;
while ( flag == 1 ) {
printf ( "请输入新地点的地名:" ) ;
scanf ( "%s" , p) ;
printf ( "请输入新地点的简介:" ) ;
scanf ( "%s" , i) ;
G- > vexnum + = 1 ;
strcpy ( G- > vex[ G- > vexnum] . name, p) ;
strcpy ( G- > vex[ G- > vexnum] . info, i) ;
FILE * fp;
fp = fopen ( filename, "at" ) ;
if ( fp == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
fprintf ( fp, "%s\n%s\n" , G- > vex[ G- > vexnum] . name, G- > vex[ G- > vexnum] . info) ;
fclose ( fp) ;
FILE * fp1;
fp1 = fopen ( filename1, "wt" ) ;
if ( fp1 == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
fprintf ( fp1, "%d %d\n" , G- > vexnum, G- > arcnum) ;
fclose ( fp1) ;
printf ( "\t\t添加地点成功,可打开\"introduce文件\"查看!" ) ;
printf ( "\n\t\t\t\t\t\t是否继续添加地点?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag ) ;
}
system ( "cls" ) ;
}
void AddRoad ( AdjMatrix * G) {
int s, e, weight;
char filename[ 30 ] = "adj.txt" ;
char filename1[ 30 ] = "flag.txt" ;
int flag = 1 ;
while ( flag == 1 ) {
PrintPlace ( G) ;
printf ( "请输入增加路线的起点序号:" ) ;
scanf ( "%d" , & s) ;
printf ( "请输入增加路线的终点序号:" ) ;
scanf ( "%d" , & e) ;
printf ( "请输入两条路线之间的距离:" ) ;
scanf ( "%d" , & weight) ;
G- > arcs[ s] [ e] = G- > arcs[ e] [ s] = weight;
FILE * fp;
fp = fopen ( filename, "at" ) ;
if ( fp == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
fprintf ( fp, "%10d %10d %10d\n" , s, e, G- > arcs[ s] [ e] ) ;
fclose ( fp) ;
FILE * fp1;
fp1 = fopen ( filename1, "at" ) ;
if ( fp1 == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
G- > arcnum + = 1 ;
fprintf ( fp1, "%d %d\n" , G- > vexnum, G- > arcnum) ;
fclose ( fp1) ;
system ( "cls" ) ;
printf ( "\t\t添加路线成功,可打开\"adj文件\"查看!" ) ;
printf ( "\n\t\t\t\t\t\t是否继续添加路线?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag ) ;
}
system ( "cls" ) ;
}
void DelRoad ( AdjMatrix * G) {
int s, e, weight, i, j;
char filename[ 30 ] = "adj.txt" ;
char filename1[ 30 ] = "flag.txt" ;
int flag = 1 ;
FILE * fp;
fp = fopen ( filename, "at" ) ;
if ( fp == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
FILE * fp1;
fp1 = fopen ( filename1, "wt" ) ;
if ( fp == NULL ) {
printf ( "\n不能打开!" ) ;
exit ( 1 ) ;
}
while ( flag == 1 ) {
PrintPlace ( G) ;
printf ( "请输入撤销路线的起点序号:" ) ;
scanf ( "%d" , & s) ;
printf ( "请输入撤销路线的终点序号:" ) ;
scanf ( "%d" , & e) ;
G- > arcs[ s] [ e] = G- > arcs[ e] [ s] = INFINITY;
fprintf ( fp, "%10d %10d %10d\n" , s, e, G- > arcs[ s] [ e] ) ;
G- > arcnum - = 1 ;
fprintf ( fp1, "%d %d\n" , G- > vexnum, G- > arcnum) ;
fclose ( fp) ;
fclose ( fp1) ;
system ( "cls" ) ;
printf ( "\t\t撤销路线成功,可打开\"adj文件\"查看!" ) ;
printf ( "\n\t\t\t\t\t\t是否继续撤销路线?\n" ) ;
printf ( "\t\t\t\t\t\t1:是\n" ) ;
printf ( "\t\t\t\t\t\t0:返回上级菜单\n" ) ;
scanf ( "%d" , & flag ) ;
}
system ( "cls" ) ;
}
void User ( ) {
int x;
int dist[ MAXVEX] ;
int path[ MAXVEX] [ MAXVEX] = { 0 } ;
AdjMatrix G;
Create ( & G) ;
while ( 1 ) {
printf ( "\t\t\t1. 校园平面图\n" ) ;
printf ( "\t\t\t2. 地点信息查询\n" ) ;
printf ( "\t\t\t3. 问路查询\n" ) ;
printf ( "\t\t\t0. 退出\n" ) ;
printf ( "\t\t\t请选择您需要的操作:" ) ;
scanf ( "%d" , & x) ;
switch ( x) {
case 1 : system ( "cls" ) ; MapOutput ( ) ; break ;
case 2 : system ( "cls" ) ; IntroducePlace ( G) ; break ;
case 3 : system ( "cls" ) ; SearchPath ( G, dist, path) ; break ;
case 0 : printf ( "\n\t\t\t\t\t\t\t" ) ; exit ( 0 ) ; break ;
default : printf ( "\n———————————————输入信息错误,请重新输入!!!————————————————————\n" ) ; break ;
}
}
}
void OwnerMeau ( AdjMatrix G) {
int c;
int x;
int dist[ MAXVEX] ;
int path[ MAXVEX] [ MAXVEX] = { 0 } ;
while ( 1 ) {
printf ( "\t\t\t1. 添加新地点\n" ) ;
printf ( "\t\t\t2. 添加新路线\n" ) ;
printf ( "\t\t\t3. 撤销旧路线\n" ) ;
printf ( "\t\t\t4. 校园平面图\n" ) ;
printf ( "\t\t\t5. 地点信息查询\n" ) ;
printf ( "\t\t\t6. 问路查询\n" ) ;
printf ( "\t\t\t0. 退出\n" ) ;
printf ( "\t\t\t请选择您需要的操作:" ) ;
scanf ( "%d" , & c) ;
getchar ( ) ;
switch ( c) {
case 1 : system ( "cls" ) ; AddPlace ( & G) ; break ;
case 2 : system ( "cls" ) ; AddRoad ( & G) ; break ;
case 3 : system ( "cls" ) ; DelRoad ( & G) ; break ;
case 4 : system ( "cls" ) ; MapOutput ( ) ; break ;
case 5 : system ( "cls" ) ; IntroducePlace ( G) ; break ;
case 6 : system ( "cls" ) ; SearchPath ( G, dist, path) ; break ;
case 0 : printf ( "\n\t\t\t\t\t\t\t" ) ; exit ( 0 ) ;
default : printf ( "\n———————————————输入信息错误,请重新输入!!!————————————————————\n" ) ; break ;
}
}
}
void Owner ( ) {
int x;
int dist[ MAXVEX] ;
int path[ MAXVEX] [ MAXVEX] = { 0 } ;
AdjMatrix G;
MapFile ( G) ;
IntroduceFile ( G) ;
AdjFile ( G) ;
Create ( & G) ;
system ( "cls" ) ;
printf ( "\t\t1.登陆\t\t\t2.注册并登录\n" ) ;
printf ( "请选择序号:" ) ;
while ( 1 ) {
scanf ( "%d" , & x) ;
switch ( x) {
case 1 : land ( ) ; OwnerMeau ( G) ; break ;
case 2 : enroll ( ) ; land ( ) ; OwnerMeau ( G) ; break ;
default : printf ( "\n———————————————输入无效,请重新正确输入!!!————————————————————\n" ) ; break ;
}
}
}
int main ( ) {
int flag;
printf ( "——————————————————————————————————————————————\n" ) ;
printf ( "\n\t\t\t欢迎使用西安邮电大学长安校区导游系统 !\n\n" ) ;
printf ( "——————————————————————————————————————————————\n" ) ;
printf ( "\n\n\n" ) ;
printf ( "\t\t1.我是游客\t\t\t2.我是管理员\n" ) ;
printf ( "请选择序号:" ) ;
while ( 1 ) {
scanf ( "%d" , & flag) ;
switch ( flag) {
case 1 : system ( "cls" ) ; User ( ) ; break ;
case 2 : system ( "cls" ) ; Owner ( ) ; break ;
default : printf ( "\n———————————————输入无效,请重新正确输入!!!————————————————————\n" ) ; break ;
}
}
}