用无向带权图实现校园导航系统
来源:互联网 发布:阿里云投诉电话 编辑:程序博客网 时间:2024/06/11 17:08
学校数据结构的课程实验之一。
用到的数据结构:无向带权图
用到的算法:Floyd最短路径算法,深度优先搜索(递归实现)
需求分析:
设计一个校园导航程序,为访客提供各种信息查询服务:
1. 以图中各顶点表示校内各单位地点,存放单位名称,代号,简介等信息;以边表示路径,存放路径长度等相关信息。
2. 图中任意单位地点相关信息的查询。
3. 图中任意单位的问路查询,即查询任意两个单位之间的一条最短的路径。
4. 从图中任意单位地点出发的一条深度优先遍历路径。
主函数:
#include <iostream>#include "School.h"using namespace std;int main(){ School mySchool=School("School.txt"); char choice='y'; while(choice=='y') { cout << "请选择操作"<<endl; cout << "--------------------------------" << endl; cout << "1----查看地点列表" << endl; cout << "2----查看地点简介" << endl; cout << "3----查询最短路径" << endl; cout << "4----从一点出发遍历" << endl; cout << "5----任意一点的可直达地点" << endl; cout << "--------------------------------" << endl; int option; cin >> option; switch (option) { case 1: mySchool.display(); break; case 2: mySchool.search(); break; case 3: mySchool.path(); break; case 4: mySchool.traverse(); break; case 5: mySchool.reachable(); break; } cout << "继续吗?[y/n]"; cin >> choice; } return 0;}
学校类:
#include <fstream>#include <string>#include "Digraph.h"using namespace std;struct Place//地点定义{ int number; string name; string introduction; Place(){} Place(int num,string nam,string intro):number(num),name(nam),introduction(intro){} void print()//显示此地点的信息 { cout<<"---------------------------"<<endl; cout<<"编号:"<<number<<endl; cout<<"地点名:"<<name<<endl; cout<<"简介:"<<introduction<<endl; cout<<"---------------------------"<<endl; }};ostream& operator<<(ostream &os, Place &aPlace)//重载输出运算符 { os << aPlace.number << ":" << aPlace.name; return os; }ofstream outFile;//输出流class School{private: int total;//总的地点数 Digraph<Place,13> places_graph; void readFile(const char filename[20])//读文件 { total = 0; ifstream inFile; inFile.open(filename); char trying; while(inFile.is_open() && !inFile.eof()) { //先试探是否为结束符 inFile >> trying; if (trying == '#') break; else { inFile.putback(trying); int number; inFile>>number; string name; inFile>>name; string introduction; inFile>>introduction; Place aPlace=Place(number,name,introduction); //aPlace.print();//显示这个地点的信息 places_graph.insert(aPlace); total++; } } for (int i = 0; i < 13; i++)//读入距离内容 for (int j = 0; j < 13; j++) { int dis; inFile >> dis; places_graph.distance_set(i, j, dis); } inFile.close(); places_graph.calculate_path();//计算所有最短路径并存入数组 cout << "学校共有" << total << "个地方"<<endl; } static void readPlace(Place &aPlace) { outFile<<aPlace.number<<endl; outFile<<aPlace.name<<endl; outFile<<aPlace.introduction<<endl; } static void print(Place &aPlace)//显示此地点的信息编号、名称 { cout<<aPlace.number<<": "<<aPlace.name<<endl; } static void visit(Place &aPlace) { cout << "->" << aPlace.number << ":" << aPlace.name << endl; }public: School(const char filename[20]) { readFile(filename); } void display() { cout<<"以下为学校的所有地点:"<<endl; places_graph.traverse(print); } void search() { cout<<"请输入要查询的地点编号:"; int num; cin>>num; Place aPlace; places_graph.search_vertex(num,aPlace);//查到要查的地点 cout<<"以下是这一地点的信息:"<<endl; aPlace.print(); } void path() { cout << "请输入想查询最短路径的两个地点的编号(如:5 7):"; int i, j; cin >> i >> j; places_graph.shortest_path(i, j); } void traverse()//深度优先遍历,输出路线 { cout << "请输入源点的编号:"; int v; cin >> v; int distance; distance = places_graph.BFS(v, visit); cout << endl << "路径总长为:" << distance<<endl; } void reachable() { cout << "请输入源点的编号:"; int v; cin >> v; cout << "和地点" << v << "有直达路径的地点如下:" << endl; places_graph.connected(v); }};
主程序流程图:
运行截图:
图类(邻接矩阵存储,因有向图是无向图的超集,所以可以定义为有向图,邻接矩阵为对称阵)
#include <fstream>#include <string>template <class Vertex,int graph_size>class Digraph{public: Digraph() { count=0; for (int i = 0; i < graph_size; i++) adjacency[i][i] = 0; } void insert(Vertex &new_entry) { nodes[count++]=new_entry; } void distance_set(int i, int j, int dis) { adjacency[i][j] = adjacency[j][i] = dis; } void traverse(void (*visit)(Vertex &))//遍历整个图(逐个访问各结点) { for(int i=0;i<graph_size;i++) (*visit)(nodes[i]); } void search_vertex(int num,Vertex &target) { target=nodes[num]; } void calculate_path()//计算最短路径并将结果更新到以上两个二维数组里 { for (int i = 0; i < graph_size; i++) { for (int j = 0; j < graph_size; j++) {//初始化路径长度数组,结点跟踪数组 shortest_dis[i][j] = adjacency[i][j]; trace_node[i][j] = j; } } cout << "这是邻接矩阵:" << endl; for (int i = 0; i < graph_size; i++) { for (int j = 0; j < graph_size; j++) cout << adjacency[i][j] << " "; cout << endl; } //Floyd算法计算任意两点之间的最短路径 for (int k = 0; k < graph_size; k++) for (int v = 0; v < graph_size; v++) for (int w = 0; w < graph_size; w++) if (shortest_dis[v][k] + shortest_dis[k][w] < shortest_dis[v][w]) { shortest_dis[v][w] = shortest_dis[v][k] + shortest_dis[k][w]; trace_node[v][w] = trace_node[v][k]; } cout << "这是最短路径数组:" << endl; for (int i = 0; i < graph_size; i++) { for (int j = 0; j < graph_size; j++) cout << shortest_dis[i][j] << " "; cout << endl; } cout << "这是结点跟踪数组:" << endl; for (int i = 0; i < graph_size; i++) { for (int j = 0; j < graph_size; j++) cout << trace_node[i][j] << " "; cout << endl; } } void shortest_path(int i, int j) { cout << "从" << i << "到" << j << "的最短路径长度为" << shortest_dis[i][j] << endl; cout << "路径为:" << endl; int k = trace_node[i][j]; cout << i ; while (k != j) { cout << "->" << k; k = trace_node[k][j];//从起点出发,找到途经结点 } cout << "->" << j << endl; } void connected(int v)//输出所有和v直达的结点 { for (int i = 0; i < graph_size; i++) { if (adjacency[v][i] != 100 && adjacency[v][i] != 0) cout << nodes[i] << " 距离为:" << adjacency[v][i] << ";" << endl; } } int BFS(int v,void (*visit)(Vertex &)) { distance = 0; bool visited[graph_size] = { false }; Vertex src = nodes[v];//找到选定的源点 visited[v] = true; (*visit)(src); for (int i = 0; i < graph_size; i++) { if (adjacency[v][i] != 100 && adjacency[v][i] != 0)//对相邻点进行深度优先遍历 traverse(i, visited, visit); } return distance; }private: int count;//结点数 int distance;//一条遍历路径总长 int adjacency[graph_size][graph_size];//存储权的邻接矩阵 Vertex nodes[graph_size];//存储结点内容的一维数组 int shortest_dis[graph_size][graph_size];//保存最短路径长度 int trace_node[graph_size][graph_size];//保存结点跟踪路径 void traverse(int v, bool visited[], void (*visit)(Vertex &))//辅助遍历函数 { if (visited[v] == false) { (*visit)(nodes[v]); visited[v] = true; for (int i = 0; i < graph_size; i++) if (adjacency[v][i] != 100 && adjacency[v][i] != 0 && visited[i] == false) { traverse(i, visited, visit);//递归地进行深度优先遍历 distance += adjacency[v][i]; } } }};
附:测试用的文件School.txt内容
前门南门;车辆进出教一楼阶梯教室;英语教室教二楼普通教室教三楼实验室;办公室;阶梯教室学一公寓男生宿舍学二公寓男生宿舍学三公寓女生宿舍学四公寓男生宿舍食堂一层;二层;清真水房在食堂旁边操场300米一圈的跑道图书馆借阅部;自习室后门北门;取快递# 1 4 8 6 100 100 10 100 1 100 10 100 0 3 4 5 100 10 100 1 100 1 100 100 3 0 10 1 7 100 6 100 10 100 100 8 4 10 0 2 100 3 100 100 6 5 9 7 5 1 2 0 3 6 9 100 7 9 8 5100 7 100 3 0 100 5 100 6 7 8 4 10 100 3 6 100 0 2 7 2 9 10 2 100 6 100 9 5 2 0 4 100 2 3 7 1 100 100 100 100 7 4 0 10 4 5 1 100 10 6 7 6 2 100 10 0 8 5 7 1 100 5 9 7 9 2 4 8 0 2 9 100 100 9 8 8 10 3 5 5 2 0 100100 8 7 5 4 2 7 1 7 9 100 0School.txt
0 0
- 用无向带权图实现校园导航系统
- 校园导航系统
- 校园导航系统
- 初探MFC之校园导航系统
- 用邻接表实现无向图
- 数据结构之用邻接矩阵实现赋值无向图,有向图,无向图
- 滨州学院信息工程学院2015级数据结构 校园导航系统的设计与实现
- Campus Guider校园导航系统 Hash算法分析
- 数据结构实践项目之校园导航系统
- 数据结构课程设计——校园导航系统开发
- ARCGis+Google map api 校园地理信息导航系统
- 数据课程设计 -——-校园导航系统
- 无向图的实现
- 无向图的实现
- 无向图的实现
- 有向图和无向图用邻接矩阵储存及代码实现
- 导航系统
- 校园导航系统——迪杰特斯拉算法
- Android应用如何支持屏幕多尺寸多分辨率问题
- 从零开始学习Python(一) 之初识python
- 欢迎使用CSDN-markdown编辑器
- 【并查集分块】Codeforces 475D CGCDSSQ
- ORACLE9i_性能调优基础一(Diagnostic and Tuning Tools)
- 用无向带权图实现校园导航系统
- 从Apriori到MS-Apriori算法
- 计算机视觉领域的一些牛人博客,研究机构等的网站链接
- 记录apache-cxf-3.0.4编写web服务的过程(2)——集合
- 【LeetCode刷题记录】Single Number
- find命令详解
- 《STL源码剖析学习笔记》
- 黑马程度员——OC语言—— @public和 @private 及 @protected
- ViewPager使用心得总结