本文是基于《数据结构》相关实验,使用迪杰斯特拉算法来实现最短路径。
总体思路是对于安徽大学磬苑校区进行数学建模,对重要的景点进行抽象。抽象成无向图中间的顶点。之后利用高德地图对各个顶点之间测距。
废话不多说,之后上代码:
首先是初始的一些操作,图和顶点的相关定义:
#define _CRT_SECURE_NO_WARNINGS
#define INFINTY 10000
#define v 20
#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct
{
int number;
char name[100];
char info[100];
}VertexType; //顶点结构
typedef struct {
VertexType vexs[20];
int arcs[20][20];//邻接矩阵
int vexnum, arcnum;//顶点个数,边的个数
}MGraph; //图结构
之后手动录入相关景点和边的数据:
void CreateGraph(MGraph &G)
{
int i,j;
G.vexnum = 16;
for (i = 0; i < 16; i++)
{//初始化路径长度均为0
for (j = 0; j < 16; j++)
{
G.arcs[i][j] = 0;
}
}
strcpy(G.vexs[0].name, "体育馆");
strcpy(G.vexs[1].name, "北体育场");
strcpy(G.vexs[2].name, "杏园宿舍");
strcpy(G.vexs[3].name, "篮球场");
strcpy(G.vexs[4].name, "理工楼D");
strcpy(G.vexs[5].name, "橘园食堂");
strcpy(G.vexs[6].name, "博学北楼");
strcpy(G.vexs[7].name, "西门");
strcpy(G.vexs[8].name, "鸣磬广场");
strcpy(G.vexs[9].name, "文典阁");
strcpy(G.vexs[10].name, "磬苑广场");
strcpy(G.vexs[11].name, "笃行南楼");
strcpy(G.vexs[12].name, "孔子像");
strcpy(G.vexs[13].name, "桂园食堂");
strcpy(G.vexs[14].name, "行政楼");
strcpy(G.vexs[15].name, "南体育场");
strcpy(G.vexs[0].info, "体育馆可以打羽毛球,做核酸");
strcpy(G.vexs[1].info, "北体育场可以踢足球,有看台");
strcpy(G.vexs[2].info, "杏园宿舍和枣园和榴园宿舍都是学生的宿舍");
strcpy(G.vexs[3].info, "篮球比赛进行的地方");
strcpy(G.vexs[4].info, "计算机科学与技术学院");
strcpy(G.vexs[5].info, "烤鸭饭,瑞辛咖啡,蜜雪冰城");
strcpy(G.vexs[6].info, "基础课专业课教学楼和自习教室");
strcpy(G.vexs[7].info, "安徽大学人流量最大的进出口");
strcpy(G.vexs[8].info, "晚上有乐队的演出");
strcpy(G.vexs[9].info, "图书馆,很多藏书,可以自习,考研圣地");
strcpy(G.vexs[10].info, "喷泉和安徽大学的标志,旁边有行知楼");
strcpy(G.vexs[11].info, "计算机实验室和化学实验室");
strcpy(G.vexs[12].info, "孔子的雕像,旁边是新闻传播学院");
strcpy(G.vexs[13].info, "安徽大学最好吃的食堂,没有之一");
strcpy(G.vexs[14].info, "政务处理,教学办");
strcpy(G.vexs[15].info, "足球场和篮球场和跑道");
G.arcs[0][1] = G.arcs[1][0] =235;
G.arcs[1][2] = G.arcs[2][1] =220;
G.arcs[2][3] = G.arcs[3][2] =130;
G.arcs[1][3] = G.arcs[3][1] =200;
G.arcs[1][4] = G.arcs[4][1] =320;
G.arcs[3][4] = G.arcs[4][3] =210;
G.arcs[2][5] = G.arcs[5][2] =240;
G.arcs[3][6] = G.arcs[6][3] =325;
G.arcs[4][10] = G.arcs[10][4] =400;
G.arcs[5][6] = G.arcs[6][5] =350;
G.arcs[6][10] = G.arcs[10][6] =220;
G.arcs[7][8] = G.arcs[8][7] =180;
G.arcs[8][9] = G.arcs[9][8] =190;
G.arcs[9][10] = G.arcs[10][9] =345;
G.arcs[5][8] = G.arcs[8][5] =310;
G.arcs[5][9] = G.arcs[9][5] =330;
G.arcs[6][9] = G.arcs[9][6] =210;
G.arcs[6][10] = G.arcs[10][6] =200;
G.arcs[11][12] = G.arcs[12][11] =300;
G.arcs[9][11] = G.arcs[11][9] =150;
G.arcs[10][11] = G.arcs[11][10] =300;
G.arcs[10][12] = G.arcs[12][10] =170;
G.arcs[11][13] = G.arcs[13][11] =225;
G.arcs[12][13] = G.arcs[13][12] =270;
G.arcs[8][13] = G.arcs[13][8] =485;
G.arcs[14][13] = G.arcs[13][14] =530;
G.arcs[12][14] = G.arcs[14][12] =510;
G.arcs[13][15] = G.arcs[15][13] =260;
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
if (i != j && G.arcs[i][j] == 0)
{
G.arcs[i][j] = INFINTY;
}
}
}
for (i = 0; i <16; i++)
{
G.vexs[i].number = i;
}
G.arcnum = 27;
}
之后我们来看相关的菜单:
void printsystem()
{
cout << endl;
cout << " 安徽大学欢迎您! \n";
cout << " AHU \n";
cout << "*****************************\n";
cout << "* 欢迎来到景点查询系统 *\n";
cout << "* 1.查看所有景点 *\n";
cout << "* 2.景点查询 *\n";
cout << "* 3.问路查询 *\n";
cout << "* 4.高级功能 *\n";
cout << "* 0.退出程序 *\n";
cout << "*****************************\n";
cout << endl;
}
主函数实现相关功能:
其中的高级功能中还二层嵌套着一个菜单:
int main()
{
int x = 10;
MGraph G;
CreateGraph(G);
printsystem();
while (x != 0)
{
cin >> x;
while (x != 1 && x != 2 && x != 3 && x != 4&& x!= 0)
{
cout << "错误,请重新输入:" << endl;
cin >> x;
}
switch (x)
{
case 1:Allprint(G); cout << endl; break;
case 2:FindGraph(G); break;
case 3:
{
int qidian;//起点
int zhongdian;
int p[v] = { 0 };//p数组为path
int D[v] = { 0 };//D数组为最短距离
cout << "请输入起点的编号:\n";
cin >> qidian;
cout << "请输入目的地:\n";
cin >> zhongdian;
Dijkstra(G, qidian, p, D);
shortpath(G,p, D, qidian,zhongdian);
break;
}
case 4:
{
cout << " 请输入你想要的相关操作: " << endl;
cout << "********************************\n";
cout << " 1.修改已有景点的相关信息 \n";
cout << " 2.增加一个新景点及其相关信息 \n";
cout << " 3. 增加一条新的路径 \n";
cout << " 4. 删除一个景点及其相关信息 \n";
cout << " 5. 删除一条路径 \n";
cout << "********************************\n";
int z;
cin >> z;
switch (z)
{
case 1:changeinfo(G); break;
case 2:addves(G); break;
case 3:addarc(G); break;
case 4:del_ves(G); break;
case 5:del_arcone(G); break;
default:cout << "输入数据错误!\n"; break;
}
}break;
case 0:x = 0; break;
}
printsystem();
cout << endl << endl;
}
cout << "谢谢您的使用,欢迎您再来安大!" << endl;
cout << " AHU永远欢迎您!" << endl;
return 0;
}
所有准备工作做好了,我们可以来到正题部分:
首先给出迪杰斯特拉算法,这部分基本和书上一样
void Dijkstra(MGraph G, int v0, int p[], int D[])
{
int judge[v];//判断v在不在当前集合中
for (int i = 0; i < G.vexnum; i++)
{
judge[i] = 0;
D[i] = G.arcs[v0][i];//初始化每个点到v0的路径长度
p[i] = 0;
}
D[v0] = 0;//自己到自己的最短路径为0
judge[v0] = 1;//把v0放入集合之中
int k = 0;
for (int i = 0; i < G.vexnum; i++)
{
int min = INFINTY;
for (int w = 0; w < G.vexnum; w++)
{
if (!judge[w])//w不在集合中
{
if (D[w] < min)
{
k = w;
min = D[w];
}
}
}
judge[k] = 1;
for (int w = 0; w < G.vexnum; w++)
{
if (!judge[w] && (min + G.arcs[k][w] < D[w]))
{
D[w] = min + G.arcs[k][w];//最短路径长度
p[w] = k;//记录点
}
}
}
}
最短路径的实现(核心为建立临时数组):
void shortpath(MGraph G,int p[], int D[], int y, int x)
{
int temp[20] = { 0 }; int j = 0; int x0 = x;//x0储存终点
while (p[x] != 0)//当p[x]非零时用temp数组储存前驱
{
temp[j] = p[x];
x = p[x];
j++;
}
j--;//指针退一位
cout << "路径为:" << endl;
cout << G.vexs[y].name;//输出起点
for (; j >=0; j--)//输出路径
{
cout << "->" << G.vexs[temp[j]].name;
}
cout << "->" << G.vexs[x0].name;//输出终点
cout << endl;
if (D[x0] == 10000) { cout << "不存在路径!" << endl; return; }
cout << "最短距离为:" << D[x0] << endl;
}
接下来看看菜单中的高级选项:
(1)修改景点信息
void changeinfo(MGraph& G)//修改景点信息
{
int x;
cout << "请输入你想要修改的编号:" << endl;
cin >> x;
if (x >= G.vexnum || x < 0) { cout << "错误!" << endl; return; }//输入的x不合法
cout << "修改名称:" << endl;
cin >> G.vexs[x].name;
cout << "修改相关信息:" << endl;
cin >> G.vexs[x].info;
cout << "成功!" << endl;
}
(2)增添一个新顶点
void addves(MGraph& G)
{
if (G.vexnum == v)
{
cout << "景点已满!" << endl; return;
}
cout << "请输入你想要增添的景点:" << endl;
cin >> G.vexs[G.vexnum].name;
cout << "请输入你想要增添的相关景点的信息:" << endl;
cin >> G.vexs[G.vexnum].info;
G.vexs[G.vexnum].number = G.vexnum;
for (int i = 0; i < G.vexnum; i++)
{
G.arcs[i][G.vexnum] = G.arcs[G.vexnum][i] = INFINTY;//目前这个点和别的点距离无限大
}
G.arcs[G.vexnum][G.vexnum] = 0;
G.vexnum++;
cout << "处理成功!" << endl;
}
(3)增添一条新边
void addarc(MGraph& G)
{
int x, y; int z;
cout << "请输入你想要增添的边相连着哪两个景点(空格分隔两个数):" << endl;
cin >> x; if (x >= G.vexnum || x < 0) { cout << "错误!" << endl; return; }//输入的x不合法
cin >> y; if (y >= G.vexnum || y < 0) { cout << "错误!" << endl; return; }//输入的y不合法
cout << "请输入此边的权值:" << endl;
cin >> z;
G.arcs[x][y] = G.arcs[y][x] = z;
G.arcnum++;
cout << "处理成功!" << endl;
}
(4)删除一个顶点(这里感觉写得不太好)
void del_ves(MGraph& G)
{
int x; int sum = 0;//sum统计一共清除了多少条边
cout << "输入你想要删除的顶点的编号:" << endl;
cin >> x;
if (x >= G.vexnum || x < 0) { cout << "错误!" << endl; return; }//输入的x不合法
strcpy(G.vexs[x].info, "空");
strcpy(G.vexs[x].name, "空");//将顶点信息为空
for (int w = 0; w < G.vexnum; w++)//清空关于x的边
{
G.arcs[w][x] = INFINTY;
G.arcs[x][w] = INFINTY;
sum++;
}
G.vexnum--;
G.arcnum = G.arcnum - sum;
cout << "处理成功" << endl;
}
(5)删除一条边
void del_arcone(MGraph& G)
{
int x; int y;
cout << "请输入你想要删除哪两个景点之间的路径(用编号表示,用空格隔开):" << endl;
cin >> x; if (x >= G.vexnum || x < 0){cout << "数据有误!" << endl; return;}
cin >> y; if (y >= G.vexnum || y < 0){cout << "数据有误!" << endl; return;}
G.arcs[x][y] = G.arcs[y][x] = INFINTY;
cout << "处理成功!" << endl;
}
以上就是本导游系统的所有代码部分了
接下来看看部分运行的图片(只展示部分):
接下来我们试一下最短路径:
(1)从体育馆到南体育场
(2) 从杏园宿舍到文典阁
(3)从橘园食堂到孔子像
以上就是本次的全部内容了。
代码仅供参考,请勿直接抄袭!请勿转载!仅供交流学习使用!谢谢~