任务背景
有一个景区,景区里面有若干个景点,景点之间满足以下条件:
- 某些景点之间铺设了道路(相邻)
- 这些道路都是可以双向行驶的(无向图)
- 从任意一个景点出发都可以游览整个景区(遍历连通图)
景区图如下:
景点数据
景区的数据包含景点信息和景点之间的道路信息。分别由两个文本文件存储。
Vex.txt文件用来存储景点信息;Edge.txt文件用来存储道路信息。
实现代码如下:
Main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"Graph.h"
#include"Tourism.h"
using namespace std;
Graph m_Graph;
int main()
{
int nSelection = -1;
do {
cout << "===== 景区信息管理系统 =====" << endl;
cout << "1.创建景区景点图" << endl;
cout << "2.查询景点信息" << endl;
cout << "3.旅游景点导航" << endl;
cout << "4.搜索最短路径" << endl;
cout << "5.铺设电路规划" << endl;
cout << "0.退出" << endl;
cout << "请输入操作编号(0~5):";
//该循环用来解决输入字符(串)后会进入死循环的问题
while (scanf("%d", &nSelection) != 1) {
//scanf函数有n个输入正确便会返回n
cout << "输入有误,请输入0~5的数字:";
while (getchar() != '\n') {
};
//内层while循环换成下面的语句也可以解决问题,但VS2017的编译器不支持fflush(stdin)函数
//fflush(stdin);
}
switch (nSelection) {
case 1: CreateGraph(); break; //创建景区景点图
case 2: GetSPotInfo(); break; //查询景点信息
case 3: TravelPath(); break; //旅游景点导航
case 4: FindShortPath(); break; //搜索最短路径
case 5: DesigePath(); break; //铺设电路规划
case 0: cout << "程序已退出\n"; system("pause"); exit(0); break;//退出
default: cout << "输入有误,请输入0~5的数字:"; break;
}
} while (nSelection != 0);
return 0;
}
Graph.h
#ifndef GRAPH_H
#define GRAPH_H
//定义顶点
struct Vex
{
int num; //景点编号
char name[20]; //景点名称
char desc[1024]; //景点介绍
};
//定义边
struct Edge
{
int vex1; //边的第一个顶点
int vex2; //边的第二个顶点
int weight; //权值
};
//定义图
struct Graph
{
int m_aAdjMatrix[20][20]; //邻接矩阵
Vex m_aVexs[20]; //顶点信息数组
int m_nVexNum; //当前图的顶点个数
};
//定义路径
typedef struct Path
{
int vexs[20]; //保存一条路径
Path *next; //下一条路径
}*PathList;
//初始化图
void Init();
//插入顶点信息
bool InsertVex(Vex sVex);
//插入边信息
bool InsertEdge(Edge sEdge);
//获取当前顶点数
int GetVexmun();
//查询指定顶点信息
Vex GetVex(int v);
//查询与指定顶点相连的边
int FindEdge(int nVex, Edge aEdge[]);
//使用深度优先搜索算法遍历图
void DFS(int nVex, bool bVisted[], int &nIndex, PathList &pList);
/*
输入参数:int nVex,顶点编号。
输入参数:bVisted[],bool 类型的数组,用来记录某个顶点是否被遍历过。
输入参数:int &nIndex,记录遍历的深度。
输出参数:PathList &pList,遍历得到的结果。
功能:使用深度优先搜索算法遍历图
*/
//通过调用 DFS()函数,得到深度优先搜索遍历结果
void DFSTraverse(int nVex, PathList &pList);
/*
输入参数:int nVex,顶点编号。
输出参数:PathList &pList,遍历得到的结果。
功能:通过调用 DFS()函数,得到深度优先搜索遍历结果。
*/
//通过Dijkstra算法求得nVexStart到nVexEnd的最短路径
int FindShortPath(int nVexStart, int nVexEnd, Edge aPath[]);
/*
输入:起始景点的编号 v1 和目的景点的编号 v2。
输出:最短路径。
功能:通过 Dijkstra 算法求得 v1 到 v2 的最短路径
*/
//通过 Prim 算法构建最小生成树
void FindMinTree(Edge aPath[]);
/*
输入:Edge aPath[]
输出:最小生成树。
功能:通过 Prim 算法构建最小生成树
*/
#endif
Graph.cpp
#include<iostream>
#include"Graph.h"
using namespace std;
//m_Graph图结构已经在主函数中定义,在此处调用
extern Graph m_Graph;
//初始化图结构
void Init()
{
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
m_Graph.m_aAdjMatrix[i][j] = 0; //权值信息初始化为0
}
m_Graph.m_nVexNum = 0; //景点数目初始化为0
}
}
//插入顶点信息
bool InsertVex(Vex sVex)
{
if (m_Graph.m_nVexNum == 20) //顶点已满
return false;
m_Graph.m_aVexs[m_Graph.m_nVexNum++] = sVex