数据结构课程设计——校园导游系统(图)
数据结构课程设计——校园导游系统
主要的任务为两个:
- 求两点间最短路径。(迪杰斯特拉算法)
- 求两点间简单路径。(dfs)
难度不大。部分有注释。
//先是MGraph中的主要算法实现
#ifndef MGRAPH_H_INCLUDED
#define MGRAPH_H_INCLUDED
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
#define MAX_VEX 20
#define MAX_NUM 32767
typedef struct vex
{
string name;
string info;
} vex, *vexptr;
//图的邻接矩阵存储表示
typedef struct
{
vex vexs[MAX_VEX]; //顶点表
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum, arcnum; //图的当前点数和边数
} MGraph;
//获取顶点位置:若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息
int LocateVex(MGraph &G, string u)
{
int index = -1; //原始下标,没找到元素返回-1
for(int i = 0; i < G.vexnum; i++) //遍历顶点数组
{
if(u == G.vexs[i].name)
{
index = i; //记录元素下标
}
}
return index; //返回下标
}
void MapOfHdu()
{
cout<<"==============简略地图(地点括号内为在顶点表中的下标)============="<<endl;
cout<<"八号楼(8)"<<endl;
cout<<" 学生活动中心(10) "<<endl;
cout<<" 图书馆(9)"<<endl;
cout<<""<<endl;
cout<<" 体育馆(5)"<<endl;
cout<<""<<endl;
cout<<" 六号楼(6) 七号楼(7) "<<endl;
cout<<""<<endl;
cout<<" 四号楼(4)"<<endl;
cout<<" 三号楼(3)"<<endl;
cout<<" 二号楼(2)"<<endl;
cout<<" 一号楼(1)"<<endl;
cout<<"============================南大门(0)============================"<<endl;
}
int CreateMap(MGraph &G)
{
G.vexnum = 11;//顶点数
G.arcnum = 17;//边数
//初始化邻接矩阵,所有边的权值置INF(MAX_NUM)
for(int i = 0; i < G.vexnum; ++i)
{
for(int j = 0; j < G.vexnum; ++j)
{
G.arcs[i][j] = MAX_NUM;
}
}
G.vexs[0].name = "南大门";
G.vexs[0].info = "南大门为学校正大门";
G.vexs[1].name = "一号楼";
G.vexs[1].info = "信仁楼";
G.vexs[2].name = "二号楼";
G.vexs[2].info = "信义楼";
G.vexs[3].name = "三号楼";
G.vexs[3].info = "信礼楼";
G.vexs[4].name = "四号楼";
G.vexs[4].info = "在建";
G.vexs[5].name = "体育馆";
G.vexs[5].info = "体育馆简介";
G.vexs[6].name = "六号楼";
G.vexs[6].info = "信诚楼";
G.vexs[7].name = "七号楼";
G.vexs[7].info = "信博楼";
G.vexs[8].name = "八号楼";
G.vexs[8].info = "信远楼";
G.vexs[9].name = "图书馆";
G.vexs[9].info = "图书馆简介";
G.vexs[10].name = "学生活动中心";
G.vexs[10].info = "学生活动中心简介";
//初始化各边权值
G.arcs[0][1] = 100;
G.arcs[0][2] = 100;
G.arcs[0][3] = 300;
G.arcs[1][2] = 250;
G.arcs[1][3] = 100;
G.arcs[2][3] = 250;
G.arcs[3][4] = 350;
G.arcs[3][8] = 1000;
G.arcs[4][5] = 500;
G.arcs[4][6] = 300;
G.arcs[4][8] = 800;
G.arcs[5][6] = 200;
G.arcs[5][10] = 900;
G.arcs[7][8] = 850;
G.arcs[7][9] = 150;
G.arcs[7][10] = 250;
G.arcs[9][10] = 150;
G.arcs[1][0] = 100;
G.arcs[2][0] = 100;
G.arcs[3][0] = 300;
G.arcs[2][1] = 250;
G.arcs[3][1] = 100;
G.arcs[3][2] = 250;
G.arcs[4][3] = 350;
G.arcs[8][3] = 1000;
G.arcs[5][4] = 500;
G.arcs[6][4] = 300;
G.arcs[8][4] = 800;
G.arcs[6][5] = 200;
G.arcs[10][5] = 900;
G.arcs[8][7] = 850;
G.arcs[9][7] = 150;
G.arcs[10][7] = 250;
G.arcs[10][9] = 150;
return 1;
}
//景点介绍
int GetInfo(MGraph &G, string u)
{
for(int i = 0; i < G.vexnum; i++)
{
if(G.vexs[i].name == u)
{
cout<<"有关该景点的信息是:";
cout<< G.vexs[i].info << endl;
return 1;
}
}
cout << "未查询到此景点!" << endl;
return 0;
}
int GetDistance(MGraph &G, string u1,string u2)
{
int id1,id2;
id1=LocateVex(G,u1);
id2=LocateVex(G,u2);
return G.arcs[id1][id2]<MAX_NUM?G.arcs[id1][id2]:-1;
}
void Dijkstra(MGraph G,int v,int dist[],int path[])
{
int Set[MAX_VEX];
int Min,u;
//对数组进行初始化//
for(int i=0; i<G.vexnum; i++)
{
dist[i]=G.arcs[v][i];
Set[i]=0;
if(G.arcs[v][i]<MAX_NUM)
{
path[i]=v;
}
else
{
path[i]=-1;
}
Set[v]=1;
path[v]=-1;
}
//关键操作//
for(int i=0; i<G.arcnum-1; i++)
{
Min=MAX_NUM;
//循环每次从剩余顶点中挑出一个顶点,它是S集通往所有顶点的路径长度最小的那个//
for(int j=0; j<G.arcnum; j++)
{
if(Set[j]==0&&dist[j]<Min)
{
u=j;
Min=dist[j];
}
}
Set[u]=1;//将选出的顶点并入最短路径中
//循环以刚并入的顶点对通往剩余顶点的所有路径进行检测//
for(int j=0; j<G.arcnum; j++)
{
//if判断顶点U的加入是否会出现通往顶点j的更短的路径,如果出现,则改变原来路径及其长度,否则不变//
if(Set[j]==0&&dist[u]+G.arcs[u][j]<dist[j])
{
dist[j]=dist[u]+G.arcs[u][j];
path[j]=u;
}
}
}
//算法结束后,dist[]中存放初始顶点v到其余顶点的最短路径长度,path[]中存放v到其余顶点的最短路径//
}
void printPath(int path[],int a)
{
//path实际上是一颗双亲存储结构的树,故需要栈来将其逆序输出//
int Stack[MAX_VEX];
int top=-1;
while(path[a]!=-1)
{
Stack[++top]=a;
a=path[a];
}
Stack[++top]=a;
while(top!=-1)
{
cout<<Stack[top--]<<" ";
}
cout<<endl;
}
int visited[MAX_VEX]= {0};
int DFSpath[MAX_VEX]= {0};
int DFStop=-1;
void DFS(MGraph & G,int v,int e)
{
visited[v]=1;
DFSpath[++DFStop]=v;
for(int i=0; i<G.vexnum; i++)
{
if(v==e)
{
for(int j=0; j<=DFStop; j++)
{
cout<<DFSpath[j]<<" ";
}
cout<<endl;
visited[v]=0;
DFStop--;
break;
}
if((G.arcs[v][i]<MAX_NUM)&&(!visited[i]))
{
DFS(G,i,e);
}
if(i==G.vexnum-1)//准备回溯前先处理栈和当前节点状态
{
DFStop--;
visited[v]=0;
}
}
}
#endif // MGRAPH_H_INCLUDED
之后是主程序实现。
#include <iostream>
#include "MGraph.h"
using namespace std;
void menu()
{
cout << "----------------------欢迎咨询校园导游系统---------------------- "<< endl;
cout << "--------------------请在屏幕上输入相应的数字--------------------- "<< endl;
cout << " 【1】. 查看地图 " << endl;
cout << " 【2】. 信息查询 " << endl;
cout << " 【3】. 最短路径查询 " << endl;
cout << " 【4】. 简单路径查询 " << endl;
cout << " 【5】. 退出程序 " << endl;
cout<< "-------------------------------------------------------------------" << endl;
}
int main(){
MGraph G;
int m;
string b;
CreateMap(G);
while(1){
menu();
cin>> m;
switch(m){
case 1:
{
MapOfHdu();
system("pause");
system("cls");
break;
}
case 2:
{
MapOfHdu();
cout << "请输入要查询的位置名称:";
cin>> b;
GetInfo(G, b);
system("pause");
system("cls");
break;
}
case 3:
{
MapOfHdu();
string v1, v2;
int v1i,v2i;
int dist[MAX_VEX],path[MAX_VEX];
cout << "请输入起点和终点:(输入名称并以空格间隔)";
cin>> v1 >> v2;
cout << v1 << "到" << v2 << "的最短路径长为:";
v1i=LocateVex(G,v1);
v2i=LocateVex(G,v2);
Dijkstra(G,v1i,dist,path);
cout<<dist[v2i]<<endl;
cout << v1 << "到" << v2 << "的最短路径为:";
printPath(path,v2i);
cout<< endl;
system("pause");
system("cls");
break;
}
case 4:
{
MapOfHdu();
string v1, v2;
int v1i,v2i;
cout << "请输入起点和终点:(输入名称并以空格间隔)";
cin>> v1 >> v2;
cout << v1 << "到" << v2 << "的所有简单路径为:"<<endl;
v1i=LocateVex(G,v1);
v2i=LocateVex(G,v2);
DFS(G,v1i,v2i);
system("pause");
system("cls");
break;
}
case 5:
return 0;
}
}
}