数据结构-- 校园导游咨询系统课程设计报告书
课题要求:
一、 基本功能:
- 设计你所在学校的校园平面图,所含景点不少于10个。以图中顶点表示校内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
- 为来访客人提供图中任意景点相关信息的查询。
- 为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。
- 增加、删除、更新有关景点和道路的信息。
二、 扩展功能:
- 定义用户类型:用户(用户编号,用户名,密码,类型),其中,类型值为0表示超级用户,为1表示普通用户,超级用户具备所有权限,普通用户只具备浏览(查询)权限。采用顺序表作为存储结构。
- 实现创建用户功能。不少于3个超级用户和是10个普通用户。
- 实现设置密码功能。用户可以修改自己的密码。
- 实现登录系统功能。当用户名和密码输入都正确后才能使用该系统。
- 用户数据以文本文件格式存储。
1 需求分析
1.1 系统概述
随着高校的发展,校园面积不断扩大,校园内跨区域活动频繁,为了给校内师生和校外人士办公、教学、生活等方面带来更大的便利,以及面对校园信息化建设的全面推广和迅猛发展,本系统将主要通过弗洛伊德算法,求出不同景点之间所需最短路径,方便访客出行,提供导游咨询,进一步加强数字化校园建设。
该系统实现功能如下:
1、多用户类型,能够提供游客和管理员两种用户模式,游客可以直接临时登录;管理员可以通过账号密码登录。可以自由添加管理员账号,并将其存储在文件中。
2、从河南工业大学的平面地图中选取出10个的景点来建立无向图。
3、为来访客人提供图中任意景点相关信息的查询。
4、为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。
5、修改、更新有关景点和道路的信息
1.2 系统中的角色
校园导游咨询系统的使用角色分为两种,一种为游客,仅拥有信息统计查询权限;另一种是管理员,拥有系统所有的权限,包括查询,修改等功能。系统中角色及其各自功能如表1所示:
角色 | 类别 | 描述 |
---|---|---|
游客 | 服务对象 | 查看学校基本信息,查看学校景点基本信息、平面图,查询景点最短路径 |
管理员 | 管理人员 | 查看学校基本信息,查看学校景点基本信息、平面图,输出全部景点信息,查询景点最短路径,修改、更新景点信息,修改、更新道路信息 |
1.3 功能性需求
1.3.1 用户类型
(1)游客:可在校园导游咨询系统上实现对校园信息的查询,查询景点信息和查看校园平面图,查询任意两景点之间的最短路径。
(2)管理员:在实现游客所有功能的前提下,具有更高级的权限,能够一输出所有景点信息,修改,更新各个景点信息,修改,更新各条道路信息。
1.3.2 查看校园详细信息
直接输出河南工业大学基本信息,供游客阅读。
1.3.3 查看该校园平面图
直接输出河南工业大学平面图,方便游客更好的了解学校各景点地理位置。
1.3.4 校园景点信息查询
通过输入的景点序号,查询该景点并输出基本信息,对其进行介绍。
1.3.5 景点最短路径查询
通过输入两个顶点的序号,最其最短路径进行查询,给出景点之间最短距离和详细的出行方式。
1.3.6 输出所有景点信息
管理员专属功能,一键输出所有景点信息,方便浏览管理。
1.3.7 修改景点基本信息
管理员专属功能,输入景点序号,查找该景点并对其景点基本信息进行修改。
1.3.8 修改路径基本信息
管理员专属功能,输入两个景点的序号来确定一条路径,然后对其路径的值进行修改。
1.4 用例图
根据校园导游咨询系统的相关功能,我们可以得到该系统的简易用例图,用例图较为详细的描述了系统的一些基本功能以及操作流程。校园导游咨询系统用例图如图1所示:
2 概要设计
2.1 抽象数据类型
ADT Guide{
数据对象:V是具有相同特性的数据元素的集合,称为顶点集
数据关系:
R={VR}
VR={<v,w>|v,w∈v且p(v,w)<v,w>表示从v到w的弧,谓词p(v,w)定义了弧<v,w>的意义或信息}
基本操作:
CreateUDG(&G)
初始条件:V是图的顶点集,VR是图中弧的集合。
操作结果:按V和VR的定义构造图。
Query(G)
初始条件:图G存在,V是G中某个顶点
操作结果:查找图中顶点的信息并将其输出。
Modify_vertex(&G)
初始条件:V是图的顶点集,图G存在,V是G中某个顶点
操作结果:查找图中顶点,并对其信息进行修改。
Modify_Edge(&G)
初始条件:V是图的顶点集,VR是图中弧的集合,图G存在
操作结果:通过顶点确定边,对边值进行修改。
Floyd (G)
初始条件:VR是图中弧的集合,图G存在
操作结果:佛洛依德算法求最短路径。
Ask(G)
初始条件:图G存在,V是G中某个顶点
操作结果:输出最短路径。
Path_Out(G, start, end)
初始条件:图G存在,V是G中某个顶点
操作结果:输出最短路径经过的顶点。
}ADT Guide
2.2 存储结构设计
本系统中采用结构体定义管理员账号密码信息、景点信息,结构体定义邻接矩阵存储图的有关信息。
2.2.1 管理员的存储定义
struct Users //账号密码
{
char account[30];
char password[30];
} use[50];
2.2.2 景点信息的存储定义
typedef struct Ver //顶点信息
{
char num[4]; //顶点代号
char name[41]; //顶点名称
char instruct[401]; //顶点说明
} Ver;
typedef struct //邻接矩阵
{
Ver vex[Max]; //顶点表
int arcs[Max][Max]; //邻接矩阵
int vexnum, arcnum; //图的当前顶点数和边数
} AMGragh;
2.2.3 系统相关函数定义
int Login_System();
int Administrator_Login();
int Registered_Account();
int Login();
void CreateUDG(AMGragh &G);
int Administrators();
int User();
void Administrators_Menu();
void User_Menu();
void Introduce();
void Map();
void Query(AMGragh G);
void All_Print(AMGragh G);
void Modify_vertex(AMGragh &G);
void Modify_Edge(AMGragh &G);
void Floyd(AMGragh G);
void Ask(AMGragh G);
void Path_Out(AMGragh G, int start, int end);
2.3 功能结构图
根据校园导游咨询系统的相关功能,我们可以得到该系统的系统功能结构图,系统结构图和用例图类似,但是更加直观的展示了各个功能的结构。校园导游咨询系统功能结构图如图2所示:
2.4 系统子程序及功能设计
本系统的各个功能模块共涉及18个函数。
2.4.1 相关函数
校园导游咨询系统相关函数及其功能描述如表2所示:
函数名称 | 功能简述 |
---|---|
Login_System | 河南工业大学校园导游咨询系统登录系统 |
Administrator_Login | 管理员登录界面 |
Registered_Account | 管理员注册账号 |
Login | 管理员账号密码登录 |
CreateUDG | 根据基本信息建图 |
Administrators | 管理员功能(开放所有功能) |
User | 用户功能(开放部分功能) |
Administrators_Menu | 管理员菜单界面 |
User_Menu | 游客菜单界面 |
Introduce | 河南工业大学简介 |
Map | 河南工业大学平面简图 |
Query | 查询景点基本信息 |
All_Print | 输出所有景点信息 |
Modify_vertex | 景点基本信息管理 |
Modify_Edge | 路径基本信息管理 |
Floyd | 弗洛伊德算法获得两点最短路径 |
Ask | 用户咨询最短路径 |
Path_Out | 获得具体路径 |
2.4.3 函数的主要关系
校园导游咨询系统函数的调用关系图描述了该系统中各个函数调用关系以及用户使用时的操作流程,通过该图对该校园导游咨询系统的结构功能能有更清晰的认知。函数调用关系图如图3所示:
3 运行环境
硬件环境:PC机内存8GB,硬盘512GB,处理器Intel® Core™ i5-8265U。
软件环境:操作系统为Windows 10家庭版操作系统。
4 开发工具和编程语言
开发工具:Dev-C++5.11,Visual Studio Code。
编程语言:C++语言。
5 详细设计
5.1 Login函数
(1)设计思想
该模块需要实现系统的管理员登陆功能。首先定义好账号、密码类型,定义标志变量flag。然后进行系统的登陆,首先输入账号,然后输入密码。定义文件指针打开文件,对输入的账号密码和文件中存储的账号信息进行匹配,如果匹配成功,进入系统;如果匹配失败,提示错误并要求重新输入,每次登录有三次机会,三次输入错误则本次登录失败并退出。
(2)涉及的数据结构
本函数涉及到账号密码信息。
(3)流程图
Login函数流程图如图4所示:
(4)关键代码
cout << "请输入帐号:" << endl;
cin >> account;
cout << "请输入密码:" << endl;
for (j = 0; j < 6; j++)
{
password = _getch();
cout << "*";
ad[j] = password;
}
FILE *fp;
fp = fopen("Date.txt", "r"); //读取文件操作
while (!feof(fp))
{
fscanf(fp, "%s %sn", &use[a].account, &use[a].password);
if ((strcmp(account, use[a].account) == 0) && (strcmp(ad, use[a].password) == 0))
{
flag = 1;
fclose(fp);
break;
}
a++;
}
5.2 Registered_Account函数
(1)设计思想
该模块需要实现系统的账号注册功能。首先定义好账号、密码类型,定义标志变量flag。再进行系统的注册,输入账号,定义文件指针打开文件,对输入的账号文件中存储的账号信息进行匹配,如果匹配成功说明该账号已被注册,提示注册失败并退出;如果匹配失败,说明该账号可以被注册,则继续输入密码,然后再次输入确认密码。如果两次密码输入不一致,提示错误并要求重新注册,如果两次密码一致,将账号密码信息存入文件并提示注册成功。
(2)涉及的数据结构
本函数涉及到账号密码信息。
(3)流程图
Registered_Account函数流程图如图5所示:
FILE *fp = fopen("Date.txt", "r");
while (!feof(fp))
{
fscanf(fp, "%s %sn", &use[a].account, &use[a].password);
if ((strcmp(account, use[a].account) == 0))
{
cout << "注册失败,该账号已存在,请重新输入!" << endl;
system("pause");
flag = 1;
fclose(fp);
break;
}
a++;
}
strcpy(use[a].account, account);
cout << "请你输入密码:" << endl;
for (i = 0; i < 6; i++)
{
password[i] = _getch();
cout << "*";
use[a].password[i] = password[i];
if (password[i] == '\r')
{
cout << "注册失败,请重新注册账号" << endl;
return 0;
}
}
fprintf(fp, "账号\t密码\n");
fprintf(fp, "%s\t%s\n", use[a].account, use[a].password);
printf("\n注册成功!!!\n");
fclose(fp);
5.3 Query函数
(1)设计思想
该模块需要实现系统的查询功能,输入待查寻询的景点编号,由于景点信息数量并不是很多,这里采用顺序查找,查找成功之后输出景点代号,信息及简介;若输入景点信息错误,查找失败输出提示该代号不存在。
(2)涉及的数据结构
本函数涉及到顶点信息和图的邻接矩阵。
(3)流程图
Query函数流程图如图6所示:
5.4 Modify_vertex函数
(1)设计思想
该模块需要实现系统的修改功能。此功能为管理员专属功能,首先输出当前所有景点信息,定义标志变量。输入要修改的景点代号,顺序查找。查找成功将该景点信息清除,重新输入信息并保存,修改成功输出提示;若查找失败提示输入错误。
(2)涉及的数据结构
本函数涉及到顶点信息和图的邻接矩阵。
(3)流程图
Modify_vertex函数流程图如图7所示:
for (int i = 0; i < G.vexnum; i++)
{
if (strcmp(c, G.vex[i].num) == 0) //字符串比较的方法进行查找
{
flag = 1;
memset(G.vex[i].name, 0, sizeof(G.vex[i].name)); //把G.vex[i].**中所有字节换做字符“0”,对字符串的初始化
memset(G.vex[i].instruct, 0, sizeof(G.vex[i].instruct));
char name1[41];
char instruct1[401];
cout << "请输入修改后的景点信息:" << endl;
cout << "景点名称:";
cin >> name1;
cout << "简介:";
cin >> instruct1;
strcpy(G.vex[i].name, name1); //字符串拷贝函数
strcpy(G.vex[i].instruct, instruct1);
cout << "修改成功!" << endl;
break;
}
}
5.5 Modify_Edge函数
(1)设计思想
该模块需要实现系统的修改功能输出平面图,此功能为管理员专属功能,输入起点和目的地的景点代号,来确定路径。然后对该路径进行查找,如果该路径存在,则对其进行修改;若路径不存在查找失败,提示输入错误。
(2)涉及的数据结构
本函数涉及到顶点信息和图的邻接矩阵。
(3)流程图
Modify_Edge函数流程图如图8所示:
cout << "请输入待修改的边(例如5 8):" << endl;
cin >> i >> j;
if ((G.arcs[i][j] != MX && G.arcs[j][i] != MX) && (i >= 1 && i <= 10) && (j >= 1 && j <= 10))
{
cout << "请输入修改后的边长(例如 6):";
cin >> k;
G.arcs[i][j] = G.arcs[j][i] = k;
cout << "修改成功!" << endl;
}
5.6 Ask函数
(1)设计思想
该模块需要实现系统的最短路径查询功能,该功能是系统的核心。
Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Floyd(佛洛依德)算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。虽然我们可以直接对每个顶点通过迪杰斯特拉算法求得所有的顶点到所有顶点的时间复杂度,时间复杂度为O(n*3),但是弗洛伊德算法更加简洁优雅。
首先输出平面图,然后输入起点和目的地,然后进行判断,输入错误输出提示;输入成功,前面已经通过基本信息建图,通过Floyd求最短路径,从后往前追溯走过的结点,并且用一个数组记录下它的位置,然后再遍历数组输出所经过的每个点的信息。
(2)涉及的数据结构
本函数涉及到顶点信息和图的邻接矩阵。
(3)流程图
Ask函数流程图如图9所示:
void Floyd(AMGragh G) //弗洛伊德算法,获得两点最短路径
{
int i, j, k;
for (i = 1; i <= G.vexnum; ++i) //初始化
for (j = 1; j <= G.vexnum; j++)
{
D[i][j] = G.arcs[i][j];
if (D[i][j] < MX && i != j)
path[i][j] = i;
else
path[i][j] = -1;
}
for (k = 1; k <= G.vexnum; k++) //更新最短路径
for (i = 1; i <= G.vexnum; ++i)
for (j = 1; j <= G.vexnum; j++)
if (D[i][k] + D[k][j] < D[i][j])
{
D[i][j] = D[i][k] + D[k][j];
path[i][j] = path[k][j];
}
}
void Path_Out(AMGragh G, int start, int end) //获得具体路径
{
int p[Max];
p[0] = end;
int i = 1;
while (start != end)
{
end = path[start][end];
p[i] = end;
++i;
}
cout << "路径:" << G.vex[start - 1].name;
i = i - 2;
while (i >= 0)
{
cout << "→" << G.vex[p[i] - 1].name;
--i;
}
cout << endl;
}
6 运行实现
校园导游咨询系统主要通过佛洛依德算法求最短路径来为用户提供更为便利的出行方式,同时提供信息查询等相关操作。该系统运行实现结果如下所示。管理员账号密码信息如表3所示,河南工业大学平面抽象图如图10所示:
系统运行主界面,提供了管理员登录、游客临时登录、和退出该系统三个选项、用户可以选择管理员登录进入管理员模式,也可以游客临时免密登录。程序运行结果如图11所示:
选择管理员登录进入管理员登录界面,可以选择账号密码直接登录进入校园导游咨询系统,也可以增添管理账号密码,然后再进行登录。管理员登录界面如图12所示:
输入1选择账号密码直接登录,输入最多有3次机会,如果输入账号密码都错误将提示输入错误并退出登录,输入时对密码进行加密,用“*”代替输入。程序运行结果如图13所示:
输入2增添管理账号密码,输入账号,在文件中对该账号进行比较,如果账号已被注册,提示注册失败并退出注册,并要求重新输入正确的账号。程序运行结果如图14所示:
输入2增添管理账号密码,输入账号,若未被注册继续输入密码,输入一次密码后要求再次输入密码进行确认,若注册成功并将账号密码信息存入文件。程序运行结果如图15所示:
注册完成后可使用该账号进行登录,输入账号密码,登录成功后进入校园导游咨询系统的管理员操作界面,管理员可以使用系统所有功能。程序运行结果如图16,17所示:
进入管理员操作界面后,输入1查看校园详细信息,输出河南工业大学的基本信息,输入2查看该校园平面图,输出河南工业大学平面图。程序运行结果如图18,19所示:
输入3对校园景点信息进行查询,输入景点代号对其进行查询并输出景点代号,景点名称,景点简介等基本信息,输入4则一键输出所有景点信息。程序运行结果如图20,21所示:
输入5查询景点之间最短路径,首先输出校园平面图,然后输入两个景点代号,通过佛洛依德算法求最短路径,输出最短路径长度和路线。程序运行结果如图22所示:
输入6修改景点基本信息,首先输出所有景点信息,然后通过输入景点代号对其进行查询,找到该景点之后可对景点信息进行修改,操作完成提示修改成功。程序运行结果如图23所示:
输入7修改路径基本信息,通过输入两个景点代号来确定路径,对该路径进行检索,找到该路径之后对其值进行修改,此时最短路径发生改变。程序运行结果如图24,25所示:
在校园导游咨询系统主菜单中输入2游客临时登录,程序运行结果如图26所示。游客操作界面与管理员操作界面一致,只是部分功能受限导致无法使用,这里不做赘述。
7 心得体会
通过此次以校园导游咨询系统为题的课程设计,使我更加扎实的掌握了有关数据结构方面的知识。虽然在设计的过程中,遇到了很多的问题,但经过不断地尝试探索以及搜索资料,最终找到了问题所在,并解决了困难。
这次课程设计,加强了我动手、思考和解决问题的能力。巩固和加深了对数据结构的理解,提高综合运用本课程所学知识的能力。培养了我选用参考书,查阅手册及文献资料的能力。培养独立思考,深入研究,分析问题、解决问题的能力。通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法和工程设计方法。做课程设计同时也是对课本知识的巩固和加强,平时看课本时,有些问题就不是很能理解,做完课程设计,那些问题就迎刃而解了。而且还可以记住很多东西。认识来源于实践,实践是认识的动力和最终目的,实践是检验真理的唯一标准。所以这个期末测试之后的课程设计对我的作用是非常大的。
这次的课程设计使我懂得了理论与实际相结合是很非常重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在整个设计过程中,构思是很花费时间的。调试时经常会遇到这样那样的错误,有的是因为粗心造成的语法错误。当然,很多也时用错了方法,总是实现不了。同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌得不够牢固。
根据我在课程设计中遇到得问题,我将在以后的学习过程中要认真上好专业实验课,多在实践中锻炼自己;写程序的过程中要考虑周到,严密;在做设计的时候要有信心,有耐心,切勿浮躁;在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错误,以便能节省调试程序的时间。
通过这次的课程设计,让我更加了解到数据结构的重要性。以及它对我们专业的发展发挥的作用。对我们而言,知识上的收获很重要,但精神上的丰收更加可喜。让我知道了学无止境的道理。我们每一个人永远不能满足于现有的成就,人生就像在爬山,一座山峰的后面还有更高的山峰在等着你。挫折是一份财富,经历是一份拥有。这次课程设计必将成为我人生旅途上一次非常难忘的回忆!
8 参考文献
[1]严蔚敏.数据结构(C语言版)[M]. 北京:清华大学出版社,2018.
[2]谭浩强.C语言程序设计[M].北京:清华大学出版社,2018.
[3]徐慧民等.C++大学基础教程[M].北京:人民邮电出版社,2005.
[4]王红梅,胡明,王涛.数据结构(C++版)[M].北京:清华大学出版社,2011.
[5]苏仕华.数据结构课程设计[M].机械工业出版社,2010.
[6]林小茶.C语言程序设计(第二版)[M].中国铁道出版社,2010.
[7]杜茂康,李昌兵等.C++面向对象程序设计(第2版) [M].北京:电子工业出版社,2011.