旅游区导游图_景区导游图

2020-02-27 其他范文 下载本文

旅游区导游图由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“景区导游图”。

旅游区导游图

题目内容: 问题描述:

设某个旅游区共有n个旅游景点(n≥10),每个旅游景点都和相邻的m个旅游景点(m≥2,m

以(Vi ,Vj ,d)的形式从键盘输入建立该旅游区的旅游景点图,其中:Vi和Vj表示两个不同的旅游景点,d表示这两个景点之间的道路距离;该旅游景点图采用邻接链表存储结构。实现要求:

⑴ 旅游景点图的输出:分别以邻接矩阵、邻接链表的方式输出该旅游景点图。⑵ 相邻景点查询:假设对于每个景点,设置有简易的信息查询,要求能给出与该景点相邻的所有景点(有直接的道路相通)及对应的距离。

⑶ 景点路线查询:假设对于每个景点,设置有景点路线查询,要求能给出从该景点出发到任一其它景点的最短简单路径及距离。

⑷ 景点路线综合查询:对于该旅游区的任意两个景点,找出它们之间的最短简单路径及距离。

⑸ 最佳旅游路线确定:假设该旅游区的入口也是出口,请确定一条最佳的旅游线路,该线路必须经过所有的旅游景点(有些景点可以重复经过)且走的路最短。⑹ 设计一个菜单,上述操作要求都作为菜单中的主要菜单项。

下: ································

#include“stdio.h” #include“malloc.h” #include “string.h” #define INFINITY

32767

/* 图的最大权值,32767是整数表示的最大值*/ #define MAX_VEX 30

/* 最大顶点数目

*/

#define MAX_VALUE 999999999

typedef int InfoType;typedef char VexType;typedef enum{DG=1, AG=2, WDG=3,WAG=4}GraphKind;/*枚举常量定义旅游景点对应的图类型*/

typedef struct Path { int vertex[MAX_VEX];int value;int count;}GPath;

typedef struct MGraph { char vexs[MAX_VEX];

/*存放图的邻接矩阵的的顶点,顶点向量

*/ int arcs[MAX_VEX][MAX_VEX];

/*存放图的邻接矩阵的边

*/ int vexnum,arcnum;

/*图的当前顶点数和弧数

*/ }MGraph;

/*图的邻接链表转换为矩阵后,图的结构定义 */

/*图的邻接矩阵存储结构中结点结构体的定义*/ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct Linknode { char adjvex;

/*邻接点在头结点数组中的位置(邻接边的弧头顶点序号)*/ InfoType info;

/*与边或弧相关的信息, 如权值

*/ struct Linknode *nextarc;

/*指向下一个表结点

*/ }LinkNode;

/*邻接边单链表的结点结构体

*/ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct VexNode { char data;

/*数据域存储顶点信息

*/ int indegree;

/*顶点的度, 有向图是入度或出度或没有

*/ LinkNode *firstarc;

/*链域指向第一个表结点(邻接边头指针)*/ }VexNode;

/*顶点结点类型定义

*/ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct {

GraphKind kind;

/*图的种类标志

*/

int vexnum;

/*顶点个数

*/ VexNode AdjList[MAX_VEX];

/*邻接表数组

*/ }ALGraph;

/*图的结构定义

*/

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct { VexType vex1, vex2;

/*弧或边所依附的两个顶点

*/ InfoType info;

/*与边或弧相关的信息, 如权值

*/ }ArcType;

/*弧或边的结构定义

*/ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Init_Graph(ALGraph * G)

/*图的初始化

*/ { do {

printf(“请确认旅游景点的类型(1:无向图。2:有向图。3:带权有向图。4:带权无向图):n”);

} scanf(“%d”, &G->kind);if(G->kind==4)printf(“旅游区导游图的类型:带权无向图n”);else {

} printf(“

●您选择的图的类型不对●n”);

while(G->kind!=4);G->vexnum=0;

/* 初始化顶点个数为0

*/ } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int LocateVex(ALGraph *G, VexType vp)

/*图的顶点定位(图的顶点定位实际上是确定一个顶点在AdjList数组中的某个元素的data域内容。)*/ {

int k;for(k=0;kvexnum;k++)if(G->AdjList[k].data==vp)return(k);

/*如果存在此顶点返回顶点数组下标值

return(-1);

/*如果没有则返回-1(图中无此顶点)

*/

*/ } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int AddVertex(ALGraph *G, char vp)

/*向图中增加顶点(向图中增加一个顶点的操作,在AdjList数组的末尾增加一个数据元素。)*/ { int k;if(G->vexnum>=MAX_VEX){ } if(LocateVex(G,vp)!=-1){ printf(“所要添加的顶点已存在!n”);printf(“图中顶点数已达到最多!n”);

return(-1);return(-1);} G->AdjList[G->vexnum].data=vp;G->AdjList[G->vexnum].indegree=0;G->AdjList[G->vexnum].firstarc=NULL;k=++G->vexnum;return k;} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int AddArc(ALGraph *G, ArcType *arc)/*向图中增加一条边(弧)(根据给定的弧或边所依附的顶点,修改单链表:无向图修改两个单链表;)*/ {

int k,j;LinkNode *p,*q;k=LocateVex(G,arc->vex1);j=LocateVex(G,arc->vex2);if(k==-1||j==-1)

/*先判断是否两个顶点重复或者是否存在这两个顶点*/

{ printf(“该两个景点为一点或两景点都不存在,错误!n”);

return(-1);} p=(LinkNode *)malloc(sizeof(LinkNode));p->adjvex=arc->vex1;p->info=arc->info;p->nextarc=NULL;

/* 边的起始表结点赋值

*/ q=(LinkNode *)malloc(sizeof(LinkNode));q->adjvex=arc->vex2;q->info=arc->info;

q->nextarc=NULL;

/* 边的末尾表结点赋值

*/ q->nextarc=G->AdjList[k].firstarc;

G->AdjList[k].firstarc=q;p->nextarc=G->AdjList[j].firstarc;G->AdjList[j].firstarc=p;

/* 是无向图, 用头插入法插入到两个单链表

*/ return(1);

/*无向图,把p和q互相连接到彼此的边点上

*/ } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ALGraph *Create_ALGraph()/*采用邻接链表作为图的存储结构建立带权有向图*/ {

char stack1[MAX_VEX],stack2[MAX_VEX],vex,k1,k2;int weight;ALGraph *G;ArcType *p;printf(“首先对旅游区导游图进行初始化:nn”);G=(ALGraph *)malloc(sizeof(ALGraph));//申请动态结点空间

Init_Graph(G);printf(“n请输入旅游区导游图的各个旅游景点代码(以字符的形式出入),当输入0时作为结束标志n”);while(1){

scanf(“%s”,stack1);/*以字符串的形式输入存储旅游区景点,一次一个的存储输入的景点存到数组中之后又在图中插入该顶点,当输入0时结束*/

vex=stack1[0];

/*用字符串可以区别结束标识,用字符存到数组中不易设置结束标志*/

} if(vex=='0')break;else AddVertex(G,vex);p=(ArcType *)malloc(sizeof(ArcType));printf(“n 从键盘输入以(Vi ,Vj ,d)的形式建立该旅游区的旅游景点图,n 其中: Vi和Vj表示两个不同的旅游景点, d表示这两个景点之间的道路距离;n 该旅游景点图采用邻接链表存储结构(当输入第一个顶点是0时表示结束):n”);

while(1){

scanf(“%s”,stack1);k1=stack1[0];

if(k1=='0')

/* 输入第一个顶点,0结束

*/ break;

else {

scanf(“%s”,stack2);scanf(“%d”,&weight);

/* 输入第二个顶点和权值

*/ k2=stack2[0];p->vex1=k1;p->vex2=k2;p->info=weight;

AddArc(G,p);printf(“n请继续输入下一条道路!n”);} } return(G);} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void output_ALGraph(ALGraph *G)

// 2:输出图的邻接链表

{

int j;LinkNode *p;

printf(“n旅游区导游图的邻接链表景点输出表示如下:n”);for(j=0;jvexnum;j++){

printf(“%c”,G->AdjList[j].data);

p=G->AdjList[j].firstarc;

while(p!=NULL)

//输出一个邻接链表的景点之后,继续输出他的其他邻接景点

} {

} printf(“-> ”);printf(“<%c,%d>”,p->adjvex,p->info);p=p->nextarc;printf(“nn”);} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void output_Find_ALGraph(ALGraph *G)

// 4:相邻景点查询并输出

{

int j;LinkNode *p;

//定义邻接边单链表结点p printf(“请输入您要查询的景点(顶点数组下标值):n”);

//从输入的景点开始找和其相邻的景点并输出权值

scanf(“%d”,&j);

p=G->AdjList[j].firstarc;

//定义邻接边头指针 while(p!=NULL){ printf(“景点%c到景点%c的距离是%d(两景点之间有相连的道路)n”,G->AdjList[j].data,p->adjvex,p->info);//第j个景点和他下一个相邻的景点和权值

p=p->nextarc;

//指向下一个结点的地址,使全部与G->AdjList[j].data直接连通的顶点全部输出,NULL时截止 } printf(“nn”);} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ListToMat(ALGraph G, MGraph &g)

/*将邻接链表转换成邻接矩阵

*/ { int k,i,j;

LinkNode *p;for(i=0;i

/*g.arcs[i][j]赋初值INFINITY

for(j=0;j

g.arcs[i][j]=INFINITY;for(i=0;i

/*把链表的数组顶点保存到数组vexs[i]} for(i=0;i

p=G.AdjList[i].firstarc;while(p!=NULL)

{

k=LocateVex(&G,p->adjvex);

/*取和p相邻的顶点下标值用于邻接*/

中*/

矩阵的下标值

*/

g.arcs[i][k]=g.arcs[k][i]=p->info;/*把权值赋值给二维数组用于矩阵输出

*/

*/

} } p=p->nextarc;

/*指向下一个邻接表结点

} g.vexnum=G.vexnum;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void display(ALGraph *G,MGraph g)

/*3:输出邻接矩阵

*/ { int i,j;ListToMat(*G, g);

/*将邻接链表转换成邻接矩阵

*/ printf(“

”);for(i=0;ivexnum;i++)printf(“%-8c”,G->AdjList[i].data);

/*输出矩阵横向顶点值

*/ printf(“n”);for(i=0;i

printf(“%c

”,G->AdjList[i].data);

/*输出矩阵竖向顶点值,每输出一行输出一次顶点*/

}

} for(j=0;j

if(g.arcs[i][j]==INFINITY)

printf(“∞

”);else printf(“%-8d”, g.arcs[i][j]);

/*每个权值占有8个字符,负号表示左端对齐

*/ } printf(“n”);//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void dijkshort_One(ALGraph F, MGraph G,int v0,int distance[], int path[])/* 带权图G从顶点v0到其他定点的最短距离distance和最短路径前驱结点的下标path*/ //带权图F从下标v0到其他顶点的最短距离diatance和最短路径下标path,path中存放了从输入的v0到其他各个顶点的最短路径的前一个顶点的下标 //基于狄克斯特拉函数的设计

{

int *S=(int *)malloc(sizeof(int)*G.vexnum);int minDis,i,j,u,p;

ListToMat(F, G);printf(“你所要开始查询的景点是:%cn”,F.AdjList[v0].data);for(i=0;i

distance[i]=G.arcs[v0][i];S[i]=0;if(distance[i]

path[i]=-1;} S[v0]=1;

//标记顶点v0已从集合T加入到集合S中(以v0为下标值的顶点)for(i=0;i

minDis=INFINITY;for(j=0;j

{

minDis=distance[j];

u=j;} } S[u]=1;

//标记顶点u已从集合T加入到集合S中(以u为下标值的顶点)

for(j=0;j

// /修改从v0到其他顶点的最短距离和最短路径

if(S[j]==0&&G.arcs[u][j]distance[u]+G.arcs[u][j]){ distance[j]=distance[u]+G.arcs[u][j];//顶点v0经顶点u到其他顶点的最短距 path[j]=u;离和最短路径

} }

//顶点v0到其他所有的顶点的最短距离已经保存在数组distance中 printf(“查询结果是:n”);for(j=0;j

if(path[j]!=-1){

printf(“从景点%c到景点%c”,F.AdjList[v0].data,G.vexs[j]);

p=path[j];

printf(“的最短距离是: %d”,distance[j]);//输出顶点v0到其他所有的顶点的最短printf(“ 途中经过的景点有:”);while(p!=-1){ printf(“ %c”,G.vexs[p]);

路径

}

p=path[p];} printf(“n”);

} else if(j!=v0)

printf(“n%c到%c : 没有通路!”,G.vexs[j],G.vexs[v0]);/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void dijkshort_Two(ALGraph F, MGraph G,int v0,int distance[], int path[])/*带权图G从顶点v0到其他定点的最短距离distance和最短路径前驱结点的下标path*/ {

int w;int S[30],i,j,k,p,min,d;ListToMat(F, G);printf(“你所要开始查询的开始景点是:%cnn”,F.AdjList[v0].data);for(i=0;i

{

distance[i]=G.arcs[v0][i];S[i]=0;if(distance[i]

//顶点v0已加入到集合S中 for(i=0;i

min=INFINITY;for(j=0;j

if(!S[j]&&distance[j]

{

} min=distance[j];k=j;} S[k]=1;

///将找到的顶点加入到集合S中 for(w=0;w

// /修改集合T中顶点的距离值

if(!S[w]&&distance[w]>distance[k]+G.arcs[k][w]){ distance[w]=distance[k]+G.arcs[k][w];} path[w]=k;}

printf(“输入你要查询的另外一个景点(下标值):”);scanf(“%d”,&d);printf(“你要查询的另外一个景点是:%cn”,G.vexs[d]);printf(“n查询结果:n”);//输出结果

if(path[d]!=-1){

printf(“从景点%c到景点%c”,F.AdjList[v0].data,G.vexs[d]);

p=path[d];printf(“的最短距离是: %d”,distance[d]);printf(“ 途中经过的景点有:”);while(p!=-1){ printf(“ %c”,G.vexs[p]);p=path[p];} printf(“n”);} } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void dfs_path(ALGraph *g,int src,int cur,int vis[],GPath *cur_path,GPath * min_path){

LinkNode * node =g->AdjList[cur].firstarc;for(;node!=NULL;node=node->nextarc)/*起始条件为node =g->AdjList[cur].firstarc*/ {

} char adj=node->adjvex;int index=LocateVex(g,adj);if(vis[index]==0){

} cur_path->vertex[cur_path->count++]=index;cur_path->value+=node->info;vis[index]=1;dfs_path(g,src,index,vis,cur_path,min_path);cur_path->count--;cur_path->value-=node->info;vis[index]=0;if(vis[src]){

} if(cur_path->count==g->vexnum){

if(cur_path->valuevalue){ memcpy(min_path,cur_path,sizeof(GPath));/*由cur_path所指内存区域复制return;sizeof(GPath)个字节到min_path所指内存区域*/ } } return;} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void best_path(ALGraph *g,int src){ int vis[MAX_VEX];memset(vis,0,sizeof(vis));GPath cur_path,min_path;memset(&cur_path,0,sizeof(GPath));/*将cur_path所指向的某一块内存中的每个字节的内容全部设置为0指定的ASCII值,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向cur_path的指针。*/ memset(&min_path,0,sizeof(GPath));/*将min_path所指向的某一块内存中的每个字节的内容全部设置为0指定的ASCII值,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向min_path的指针。*/

min_path.value=MAX_VALUE;dfs_path(g,src,src,vis,&cur_path,&min_path);if(min_path.value!=MAX_VALUE){

int i=0;printf(“n最佳旅游路线景点下标值是:n”);for(i=0;i

printf(“%d->”,min_path.vertex[i]);} printf(“n”);printf(“n最佳旅游路线景点是:n”);

for(i=0;i

{

printf(“%c-> ”,g->AdjList[min_path.vertex[i]].data);

} } printf(“n”);}else { printf(“建立的图中没有最佳路径n”);}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*------------菜单------------*/ void main(){

int n,v0;MGraph g;int distance[MAX_VEX],path[2*MAX_VEX];ALGraph *G;

printf(“

============================n”);

printf(“

!欢迎使用旅游区导游系统

!n”);printf(“

============================n”);do { printf(“n请选择对该旅游区导游图的操作→nn”);

printf(“

┏━━━━━━━━━━━━━━━━━━━━━┓n”);printf(“

1.建立旅游区导游图的邻接链表存储

┃n”);printf(“

2.旅游区导游图的邻接链表的输出

┃n”);printf(“

3.旅游区导游图的邻接矩阵的输出

┃n”);printf(“

4.相邻景点查询

┃n”);printf(“

5.景点路线查询

┃n”);printf(“

6.景点路线综合查询(查询两景点最短路径)┃n”);printf(“

7.最佳路径

┃n”);printf(“

8.退出

┃n”);printf(“

┗━━━━━━━━━━━━━━━━━━━━━┛n”);do { } scanf(“%d”,&n);while(n9);switch(n){ case 1:

{

G=(ALGraph *)malloc(sizeof(ALGraph));/*动态申请图G的内存空间*/ G=Create_ALGraph();printf(“nn”);break;

} case 2:

{

} {

printf(“n旅游导游图的邻接链表表示如下所示:n”);output_ALGraph(G);printf(“nn”);break;case 3:

printf(“n旅游区导游图的邻接矩阵表示如下所示:n”);printf(“n∞表示两景点之间不存在连通的路线n”);printf(“n数值表示两景点之间的路线长度n”);display(G,g);printf(“nn”);break;

}

case 4:

{

}

case 5:

{

}

case 6:

{

}

case 7:

{

}

} } while(n!=8);} output_Find_ALGraph(G);printf(“nn”);break;printf(“输入你要查询的景点(下标值):”);scanf(“ %d”,&v0);dijkshort_One(*G,g,v0,distance,path);break;printf(“输入你要查询的开始景点(下标值):”);scanf(“ %d”,&v0);dijkshort_Two(*G,g,v0,distance,path);break;printf(“输入你要查询的开始景点(下标值):”);scanf(“%d”,&v0);printf(“景点是%c ”,G->AdjList[v0].data);best_path(G,v0);break;

《旅游区导游图.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
旅游区导游图
点击下载文档
相关专题 景区导游图 旅游区 导游图 景区导游图 旅游区 导游图
[其他范文]相关推荐
    [其他范文]热门文章
      下载全文