资源描述
1. 需求分析
1、1创建结点(旅游景点)
创建该旅游景点就是在顺序表中完成得,在顺序表中,首先要创建结点结构体,将该结构体命名为SeqList,成员变量有数组list与size,分别用来表示最大元素个数(即旅游景点得最大个数)与顺序表中当前存储得数据元素个数,顺序表可以完成得功能有求当前数据元素个数,插入数据元素,删除数据元素,取数据元素.
1、2创建图
在构造图得操作中包括结点得插入(实参包括AdjMGraph *G,DataTyp v[],n,RowColWeight E[],e)分别表示在该*G得结构体中得SeqlistVertices[]中插入结点,在*G得结构体中得edge[MaxVertices][MaxVertices]得边数组中插入边信息结点分别为行下标、列下标、权值,该*G得结构体中numOfEdges,e表示边得条数,即将e得值给它。结点得顺序表初始化,在该函数中也应包括一个结构体边信息结构体:成员包括行下标、列下标、权值.并将该结构体命名为RowColWeight。
1、3图得实现
在该函数中要使用SeqList头文件,在该文件中要真正进行插入边与结点.首先在该函数中应该定义一个结构体AdjMGraph,在该结构体得成员变量包括存放结点得顺序表定义为SeqlistVertices[]、存放边得邻接矩阵用edge[MaxVertices][MaxVertices]表示,边得条数numOfEdges。初始化AdjMGraph中得成员变量线性表与边数及存放边得邻接矩阵。然后在顺序表中插入结点,在邻接矩阵中插入边,删除边,删除结点。取序号为V得结点得第一个邻接结点,取序号为V1得邻接结点V2结点得下一个邻接结点
1、4求最短路径
在该函数中,应该有四个参数,两个位输入参数,分别为带权图G与源点(景点起点)序号v0,两个为输出参数,分别为distance[]与path[],distance[]用来存放达到得从源点v0到其余各结点得最短距离,path[]用来存放最短路径得下标.
1、从江西农业大学得平面地图中选取出6个有代表性得景点。
2、为来访得客人提供图中任意景点得路径查询,即查询任意两个景点之间得最短简单路径。当用户输入正确时,为用户输出任意两景点得最短路径;当用户输入不合法时,提示用户输入有误并返回让用户重新输入。
3、为来访客人推荐参观最短路线.
2、概要设计
1.首先用邻接矩阵存储校园图.
2。用数据结构知识创建校园图。
3.手动给校园图赋上相关信息(景点名称、代号、简介),路径及路径长度。
4.利用C语言知识编写查找景点相关信息得程序。
5.利用迪杰斯特拉算法计算任意两点之间得最短路径。
6。最后用一个主函数main输出各项结果。
1.创建校园图:
(1)先定义节点个数N,边得最大值(Maxweight),节点(景点名称、景点信息),邻接点,边,顶点向量,当前顶点数与边数。
(2)先给一个节点赋上其相关信息,然后再用p = (Node)malloc(sizeof(edgenode))语句申请下一结点,再给所申请得节点赋上相关信息,直到节点数为N=6为止。
(3)读入道路得起始点,为邻接矩阵得边赋相应得值。时
(4)节点与边得相关信息都弄好了后,校园图也就创建好了.
2.利用函数Name给10个节点赋上相应得名称,利用函数Information给各节点添加相应得介绍信息。
3.利用函数travgraph来查找景点信息,要查找景点名称时调用Name函数,要查找景点介绍信息时调用Information函数.
4。手动创建一个校园图AdjMGraphgcreat(AdjMGgrph *G),然后为相应得边赋上真正得值。
5。用distance[]数组来存放任意两景点之间得最短路径.
6.用main函数来输出结果:用switch语句分别输出,要创建校园图时调用AdjMGraphgraphcreat函数;查找景点相关信息时调用search函数;要查找任意两景点之间得最短路径时,先输入您目前所在得位置,再输入您得目得地,最后调用path函数。
3. 详细设计
#define N 10
#define MAXSize 20 //图中顶点数得最大值
#define MAXedg 30 //图中边数得最大值
#include 〈stdio、h〉
#include 〈string、h>
#include <stdlib、h>
#include <conio、h>
typedef int AdjMGraph[ MAXSize][ MAXSize];//存放邻接矩阵得权值信息
typedef struct
{
int vexs[ MAXSize];
AdjMGraph s;//
}Matrix_Graph;//图得邻接矩阵表示法。
typedef struct numofedge//
{
ﻩint adjvex; //邻接矩阵结点序号
ﻩint length; //定义道路长度
ﻩchar info[10]; //定义景点名称
ﻩchar info2[100]; //定义景点详细信息
ﻩstruct numofedge *next;//定义指向下一个结点得指针
}numofedge, *Node ;//将该结构体重新命名为*Node
typedef struct
{
ﻩchar name[10]; //存储景点得名称数组
ﻩchar information[100]; //具体得介绍此景点信息数组
ﻩstruct numofedge *link; //指向下一个景点得指针
}vextices; //创建景点及其信息结构体
typedef struct Edge
{
ﻩint lengh; //边得权值,表示路径长度、
ﻩint ivex, jvex; //表示两个连接得结点得位置变量
ﻩstruct Edge *next; //指向下一条边得指针变量
} EdgeType;
//边及其信息、
typedef struct
{
int num; //结点编号。
ﻩchar name[10]; //结点名称
} vertex;//存放结点信息结构体
typedef struct
{
ﻩvertex vexs[ MAXSize]; //存放结点数组元素信息
ﻩint edges[ MAXSize][ MAXSize]; //存放边得邻接矩阵
}adjmax,adj; //表示图得结构体
FILE *fp; //文件得读取
void clrscr() //清屏
{
system(”cls");
}
void creatgraph(vextices g[],int *n, EdgeType e[],adjmax *adj) //创建校园图vextices g[]表示存放景点信息数组 ,n表示下一个景点,EdgeType e[]表示存放边得信息数组,adjmax *adj表示下一条边得信息数组
{
int b,i,s,d,len;//b代表结点之间得边数
ﻩstruct numofedge *p,*q; //定义图得结构体
if((fp = fopen("",”r")) == NULL) //打开文件,对文件进行读得操作
{
ﻩprintf(”文件打开错误!\n");
getchar();//获取景点信息
exit(0);
}
fscanf(fp,”%d %d\n",n,&b); //读入景点个数与边数
for(i = 1; i <= *n; i++)
{
ﻩﻩfscanf(fp,”%s %s\n",&g[i]、name,&g[i]、information);//读入文件中结点(景点)得名字与详细介绍信息
strcpy(adj->vexs[i]、name,g[i]、name);//将景点得名字赋给图中得结点信息
ﻩ g[i]、link = NULL; //初始化节点得下一个结点信息
}
ﻩfor(i = 1; i <= b; i++)
ﻩ{
ﻩﻩfscanf(fp,"%d %d %d\n",&e[i]、lengh,&e[i]、ivex,&e[i]、jvex); //读入道路长度与边得行下标与列下标
s = e[i]、ivex; //将边得行号记录给S,将边得列号记录下来。
ﻩﻩd = e[i]、jvex;
ﻩ len = e[i]、lengh;//将各个边得长度值记录下来
ﻩﻩadj->edges[s][d] = e[i]、lengh; //为邻接矩阵中相应得边赋值
adj->edges[d][s] = e[i]、lengh;//该矩阵为对称矩阵故 edges[d][s]=edges[s][d];
ﻩp = (Node)malloc(sizeof(numofedge)); //为一个新得结点开辟动态空间。
p—〉next = NULL;//初始化开辟空间得下一个结点
q = (Node)malloc(sizeof(numofedge));//为一个新得结点开辟动态空间
q—〉next = NULL;//初始化开辟空间得下一个结点
p->adjvex = d; // 将边得列号给结点信息得结构体中记录邻接矩阵得序号成员
ﻩ p—>length = len;//将边得长度值给结点信息得结构体中得道路成员
ﻩﻩstrcpy(p—>info,g[d]、name); //为景点赋名称
ﻩ strcpy(p->info2,g[d]、information); //为景点赋介绍信息
ﻩq—〉adjvex = s; // 为景点赋序号,道路长度
ﻩﻩq->length = len;
ﻩstrcpy(q—〉info,g[s]、name); //为景点赋名称
ﻩﻩstrcpy(q->info2,g[s]、information); //为景点赋介绍信息
p->next = g[s]、link; //使p指针指向第s行得下一行,头插法建立邻接表
g[s]、link = p;//使p指针指向第s行得下一行得下一行
ﻩﻩq-〉next = g[d]、link;//使q指针指向第d列得下一列,头插法建立邻接表
g[d]、link = q;//使q指针指向第d列得下一列,头插法建立邻接表
ﻩ}
printf(”校园旅游图已经建立!\n");
getchar();
}
void Name(int i)
{
ﻩswitch(i)//为景点添加具体得名字地点
{
ﻩcase 1:
ﻩﻩprintf(”1:一教\n");break;
ﻩcase 2:
ﻩ printf(”2:二教\n”);break;
case 3:
ﻩprintf(”3:五教\n");break;
case 4:
printf("4:新图书馆\n”);break;
ﻩcase 5:
printf("5:老图书馆\n”);break;
case 6:
printf("6:北区食堂\n");break;
case 7:
printf(”7:南区食堂\n”);break;
case 8:
ﻩprintf("8:大学生活动中心\n”);break;
case 9:
ﻩﻩprintf("9:圆形报告厅\n");break;
ﻩcase 10:
printf(”10: 体育馆\n”);break;
default:
ﻩ printf("景点编号输入错误!请输入1->10得数字编号!\n\n”); break;
}
} /*Name*/
void Information(int i)
{/*景点介绍*/
switch(i)//为景点添加介绍信息
{
ﻩcase 1:
printf("一教:这就是一栋比较古老得建筑楼,但就是当您路过这里,会听到朗朗得读书声,很励志得地方\n");break;
ﻩcase 2:
ﻩprintf("二教: 这栋楼真得很令人不满意,,不瞧平面图很难找到,其次,它就就是一个2得形状\n");break;
ﻩcase 3:
printf("五教: 这栋教学楼应该就是新建得,总体瞧上去还令人比较满意,周边环境也挺好得\n");break;
case 4:
ﻩprintf("新图书馆:虽然很小,但就是还过得去,学习环境很好,还有自修室,阅览室等学习场所 \n");break;
case 5:
ﻩprintf(”老图书馆:很少去,听说藏得书一般就是艺术类得书籍,建筑学,美术还有音乐方面等书籍\n”);break;
case 6:
printf("北区食堂: 有时候味道太重,太咸,但就是平时味道不错,就是学生就餐得主要餐厅。\n\n");break;
ﻩcase 7:
ﻩﻩprintf("南区食堂: 味道偏清淡,三楼得南昌风味得快餐店味道较好\n");break;
ﻩcase 8:
printf(”大学生活动中心:在体育馆旁边,举办活动得主要场所,每次晚上路过那里都会听到在举办活动,很热闹\n");break;
case 9:
ﻩﻩprintf("圆形报告厅: 太小了,如果要求全院得人都参加专业类得报告,则会有很多晚来得人站在后面,没有足够得座位\n”);break;
ﻩcase 10:
printf("体育馆: 上体育课得主要场地,比较空旷,平时会有很多学生在那里训练,打羽毛球得时候与练轮滑得时候最精彩了\n”);break;
default:
ﻩﻩprintf("景点编号输入错误!请输入1->10得数字编号!\n\n"); break;
}
}/*Information*/
void searchgraph(vextices g[],int n,adjmax adj) //1查找指定景点信息
{
ﻩint i = 1,flag = 1,len; //len存储要查询得景点得序号
ﻩchar ch;
printf("请输入您要查询得景点序号:\n”);//提示用户输入景点序号
scanf("%d",&len);
getchar();//获取该序号对应得景点名称与景点信息
printf(”此景点得名称就是:”);
ﻩName(len);
ﻩprintf(”此景点得介绍就是:”);
ﻩInformation(len);
ﻩdo{
ﻩprintf("就是否继续? Y/N”);
ﻩ scanf("%c",&ch);
ﻩ getchar();
ﻩﻩif(ch == 'Y' || ch == ’y’) //继续
ﻩ{
flag = 1;
ﻩ ﻩi = 1;
ﻩ ﻩprintf("请输入您要查询得景点序号:\n");
ﻩ scanf("%d",&len);
ﻩ getchar();
ﻩﻩﻩprintf("此景点得名称就是:");
ﻩName(len);
printf("此景点得介绍就是:");
ﻩInformation(len);
ﻩﻩ continue ;
ﻩﻩ}
ﻩelse
ﻩ flag = 0; //不继续
ﻩbreak;
}while(1);
}
void creat(Matrix_Graph *G)
{
ﻩint i,j;
ﻩfor(i=1;i〈=N;i++) G—>vexs[i]=i;//初始化,0号位不用。
for(i=1;i<=N;i++)
ﻩfor(j=1;j〈=N;j++) G->s[i][j]=0;//初始值为0.
ﻩ G—〉s[1][2]=2;G—〉s[1][9]=5;//表示景点一到景点二得距离就是2。
ﻩG—〉s[2][1]=2;G—〉s[2][3]=5;G—〉s[2][4]=4;G->s[2][9]=6;//将景点间得距离初始化
G-〉s[3][2]=5;G->s[3][4]=7;G->s[3][7]=5;G->s[3][9]=6;G-〉s[3][10]=6;
ﻩ G->s[4][2]=4;G->s[4][6]=7;G->s[4][10]=7;
ﻩﻩG->s[5][6]=4;G—>s[5][7]=6;G-〉s[5][8]=8;
G-〉s[6][4]=7;G->s[6][5]=4;G->s[6][7]=3;G->s[6][10]=7;
ﻩ G—>s[7][6]=3;G-〉s[7][8]=4;G-〉s[7][10]=6;
G-〉s[8][5]=8;G->s[8][7]=4;G->s[8][9]=9;
ﻩG->s[9][1]=5;G—>s[9][2]=6;G—>s[9][3]=6;G-〉s[9][8]=9;
G->s[10][3]=6;G->s[10][4]=7;G-〉s[10][6]=7;G->s[10][7]=6;
for(i=1;i<=N;i++)
ﻩ for(j=1;j〈=N;j++)
ﻩﻩ ﻩif(G—〉s[i][j]==0) G-〉s[i][j]= MAXSize;//没有被重新赋值得,表示两景点之间
ﻩﻩ//没有路,用MAX表示无穷大.
}
void ﻩMindistance(Matrix_Graph *G,int s,int e)
{
ﻩint i,j,u,c=1,t,v;
ﻩint r[N+1][N+1];//用来存放路径上得景点.
ﻩint T[N],flag[N],d[N];
ﻩfor(i=0;i<=N;i++)
for(j=0;j<=N;j++) r[i][j]=0;//初始值为0.
ﻩ for(i=1;i<=N;i++)
ﻩ {
T[i]=-1;//初始值为—1。
ﻩ flag[i]=1;//初始值为1。
ﻩ d[i]= MAXSize;//路径长度初始值为无穷大,用MAX表示.
ﻩ}
ﻩ flag[s]=0;//修改标识.
while(c〈=N)
ﻩ {
ﻩﻩ t= MAXSize;
ﻩ for(i=1;i<=N;i++)
ﻩﻩﻩﻩif(flag[i]&&G—>s[s][i]<t)//求最短路径,求从起点到终点得所有距离加起来得最短路径
ﻩﻩﻩ {
ﻩ ﻩﻩt=G—〉s[s][i];v=i;r[v][1]=v;}
ﻩﻩ ﻩfor(i=1;i<=c;i++)
ﻩ for(j=1;j〈=N;j++)
ﻩﻩ ﻩﻩif(flag[j]&&d[i]+G-〉s[T[i]][j]〈t)
{
ﻩ ﻩt=d[i]+G—>s[T[i]][j];v=j;
ﻩﻩﻩ ﻩ if(r[v][0]!=—1)
ﻩﻩﻩ {
ﻩﻩ ﻩ u=1;
ﻩﻩ ﻩ ﻩwhile(r[T[i]][u]!=0)
ﻩﻩﻩﻩ ﻩﻩ{
ﻩ ﻩﻩ ﻩ ﻩr[v][u]=r[T[i]][u];u++;}
ﻩﻩﻩﻩ}
ﻩ ﻩﻩﻩﻩr[v][u]=v;
ﻩﻩﻩﻩﻩ}
ﻩﻩﻩﻩ ﻩr[v][0]=—1;
ﻩ ﻩ ﻩT[c]=v;
ﻩ flag[v]=0;
ﻩﻩﻩ ﻩﻩd[c]=t;
ﻩ ﻩﻩﻩ c++;
ﻩ}
ﻩ printf(”\nThe path is:\n(%d)”,s);
j=1;
ﻩﻩwhile(r[e][j]!=0)
ﻩ {
ﻩﻩ printf("-->(%d)",r[e][j]);j++;}//显示路径。
ﻩ printf("\n\n”);
}
int main()//主函数
{
ﻩint i,j;
ﻩMatrix_Graph G;
creat(&G);
int n = 0; //景点数目
ﻩvextices g[ MAXSize]; //1保存顶点及其信息
EdgeType e[MAXedg]; //保存边及其信息
adjmax adj; //保存边与定点
ﻩchar choice = 'x';
while(1)
ﻩ{
ﻩﻩclrscr();
printf(”\n\n\t\t\t***校园导游系统***\n\n”);//提示用户正确根据需要输入数字
ﻩprintf("\t\t\t1、 文件读入并创建校园图:\n\n”);
ﻩ printf(”\t\t\t2、 查询景点详细信息:\n\n");
ﻩprintf(”\t\t\t3、 查找两景点间最短路径:\n\n");
printf(”\t\t\t0、 退出\n\n");
ﻩﻩprintf(”Please enter your choice(0-3):\n ");
ﻩﻩchoice = getchar();
ﻩﻩswitch(choice)
ﻩ{
case '1':
ﻩ clrscr();
ﻩ creatgraph(g,&n,e,&adj); //创建图(景点,景点数,边,边与景点)
ﻩ ﻩprintf("\n打开文件错误\n");
getchar();
break;
ﻩﻩcase ’2':
ﻩ ﻩclrscr();
ﻩ searchgraph(g,n,adj);//查询景点信息
ﻩﻩgetchar();
break;
ﻩ case ’3':
ﻩ clrscr();
ﻩ ﻩprintf("\2您目前得位置就是:\n");
scanf(”%d",&i);
ﻩﻩgetchar();
ﻩ ﻩprintf(”\2您得目得地就是:\n”);
ﻩscanf("%d",&j);
ﻩ ﻩgetchar();
ﻩ Mindistance(&G,i,j);//查找最短路径
ﻩgetchar();
creat(&G);
ﻩﻩﻩdo{
ﻩ ﻩﻩprintf(”就是否继续? Y/N");
ﻩﻩﻩchar ch;
ﻩﻩ ﻩint flag=1;
ﻩﻩ scanf("%c",&ch);
ﻩﻩﻩﻩgetchar();ﻩ
ﻩﻩﻩif(ch == 'Y' || ch == 'y') //就是否继续
ﻩﻩﻩ {
ﻩ ﻩﻩflag = 1;
ﻩ ﻩﻩﻩi = 1;
ﻩ printf(”\2您目前得位置就是:\n");
ﻩ ﻩﻩﻩscanf("%d",&i);
ﻩ ﻩﻩﻩgetchar();//获取输入得数字对应得地点
ﻩﻩ printf(”\2您得目得地就是:\n");
ﻩ scanf(”%d”,&j);
ﻩﻩ getchar();
ﻩ ﻩﻩMindistance(&G,i,j);//查找最短路径
ﻩ ﻩgetchar();
ﻩ creat(&G);
ﻩ continue ;
ﻩﻩ}
ﻩ ﻩﻩelse
ﻩﻩﻩ flag = 0; //不继续
ﻩﻩﻩ break;
}while(1);
ﻩ ﻩbreak;
ﻩcase ’0':
ﻩ clrscr();
ﻩﻩ printf(”\n*******按任意键退出********\n");
ﻩgetchar();
ﻩﻩexit(0);
ﻩﻩbreak;
ﻩdefault:
ﻩﻩ printf("\n输入错误,请重新输入0-3之间得数字:\n");
ﻩﻩgetchar();
ﻩ break;
ﻩﻩ}
}
ﻩgetchar();
}
4. 调试分析
4、1测试数据
当起点输入11终点输入10时,景点不存在,程序提示重新输入;当起点输入0(教学主楼)终点输入10时,终点景点不存在,程序提示重新输入;当起点输入3(五教)终点输入4(新图书馆)时,景点都存在,屏幕打印出两景点最短路径:五教—〉新图书馆,最短路径约为6.当输入1时,则按景点编号查询,当输入6(北区食堂)时,屏幕上打印出此景点信息: 有时候味道太重,太咸,但就是平时味道不错,就是学生就餐得主要餐厅;当输入4(新图书馆)时,屏幕上打印出此景点信息:虽然很小,但就是还过得去,学习环境很好,还有自修室,阅览室等学习场所
;当输入12时,此景点不存在,当输入20时,此景点不存在,当输入5时,则按景点名称查询,当在选择主菜单中输入3时,则系统推荐旅游路径:
当输入1正确输入起点(2)(二教)与终点(4)(新图书馆),屏幕将打印出两景点之间得最短路径:二教—〉五教—>图书馆,最短路径为约4m.用户应瞧清代码允许输入得范围当输入得景点代号不在(1—10)之间时,则结构也错误。
当在选择主菜单选择3时,则按景点信息查询,当输入4(新图书馆)时,屏幕上打印出此景点信息:虽然很小但还过得去,学习环境很好,还有自修室与阅览室;如图所示为输出结果.当输入8(大学生活动中心)时,屏幕上打印出此景点信息:在体育馆旁边,举办活动得主要场所,每次晚上路过那里都会听到在举办活动,很热闹,当输入12时,此景点不存在,输入信息错误
在选择主菜单输入错误时,程序不作反应,当输入e时,则退出,
由于本人得设计能力有限,在设计过程中难免出现错误。本程序在调试时,出现了一个很棘手得错误,出现了结构体变量定义错误,本来要用到指针得没有用得,经过自己得多次修改,没有编译成功,最后在同学帮助下,结构体成员定义为指针变量成功得修改了那个问题。还有一些简单得语法错误,这些错误可以通过自己慢慢调试,属于小错误就不一一列举了。
本程序得时间复杂度主要发生在求最短路径时,即算法里面得for循环语句,for循环语句三层嵌套,所以时间复杂度为n3。
5. 总结
1. 算法中可以使用顺序表存储各个结点
2. 创建图得过程可以存放在一个独立得头文件中,写出函数体,然后直接调用另一头文件
3. 在图得存储时本程序采用得邻接矩阵,也可以采用邻接表;在求两景点之间得最短路径时本程序采用得狄克斯特拉算法,也可以采用弗洛伊德算法。
4、 在本次课程设计中让我进一步熟悉了各种算法得使用,但感到自己在算法设计中还存在很大得不足,写算法时无法脱离课本,更就是需要同学得帮助,甚至有得算法不得不从网上查询,今后自己将更努力学习这门语言,多接触解决各种问题得各种算法,这样才能提高自己
5、 通过这次编程实现校园导游咨询系统,让我更深入得了解了最短距离得算法思想,查阅了很多得资料,像代码中得读写文件得语句如何使用及清屏函数。
展开阅读全文