码迷,mamicode.com
首页 > 其他好文 > 详细

用无向带权图实现校园导航系统

时间:2015-04-16 01:09:46      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

学校数据结构的课程实验之一。

用到的数据结构:无向带权图

用到的算法:Floyd最短路径算法,深度优先搜索(递归实现)

需求分析:

  设计一个校园导航程序,为访客提供各种信息查询服务:

1. 以图中各顶点表示校内各单位地点,存放单位名称,代号,简介等信息;以边表示路径,存放路径长度等相关信息。

2. 图中任意单位地点相关信息的查询。

3. 图中任意单位的问路查询,即查询任意两个单位之间的一条最短的路径。

2. 从图中任意单位地点出发的一条深度优先遍历路径。

主函数:

 1 #include <iostream>
 2 #include "School.h"
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     School mySchool=School("School.txt");
 8     char choice=y;
 9     while(choice==y)
10     {
11         cout << "请选择操作"<<endl;
12         cout << "--------------------------------" << endl;
13         cout << "1----查看地点列表" << endl;
14         cout << "2----查看地点简介" << endl;
15         cout << "3----查询最短路径" << endl;
16         cout << "4----从一点出发遍历" << endl;
17         cout << "5----任意一点的可直达地点" << endl;
18         cout << "--------------------------------" << endl;
19         int option;
20         cin >> option;
21         switch (option)
22         {
23         case 1: mySchool.display(); break;
24         case 2: mySchool.search(); break;
25         case 3: mySchool.path(); break;
26         case 4: mySchool.traverse(); break;
27         case 5: mySchool.reachable(); break;
28         }
29         cout << "继续吗?[y/n]";
30         cin >> choice;
31     }
32     return 0;
33 }

图类(邻接矩阵存储,因有向图是无向图的超集,所以可以定义为有向图,邻接矩阵为对称阵)

技术分享
  1 #include <fstream>
  2 #include <string>
  3 
  4 template <class Vertex,int graph_size>
  5 class Digraph
  6 {
  7 public:
  8     Digraph()
  9     {
 10         count=0;
 11         for (int i = 0; i < graph_size; i++)
 12             adjacency[i][i] = 0;
 13     }
 14     void insert(Vertex &new_entry)
 15     {
 16         nodes[count++]=new_entry;
 17     }
 18     void distance_set(int i, int j, int dis)
 19     {
 20         adjacency[i][j] = adjacency[j][i] = dis;
 21     }
 22     void traverse(void (*visit)(Vertex &))//遍历整个图(逐个访问各结点)
 23     {
 24         for(int i=0;i<graph_size;i++)
 25             (*visit)(nodes[i]);
 26     }
 27     void search_vertex(int num,Vertex &target)
 28     {
 29         target=nodes[num];
 30     }
 31     void calculate_path()//计算最短路径并将结果更新到以上两个二维数组里
 32     {
 33         for (int i = 0; i < graph_size; i++)
 34         {
 35             for (int j = 0; j < graph_size; j++)
 36             {//初始化路径长度数组,结点跟踪数组
 37                 shortest_dis[i][j] = adjacency[i][j];
 38                 trace_node[i][j] = j;
 39             }
 40         }
 41         cout << "这是邻接矩阵:" << endl;
 42         for (int i = 0; i < graph_size; i++)
 43         {
 44             for (int j = 0; j < graph_size; j++)
 45                 cout << adjacency[i][j] << " ";
 46             cout << endl;
 47         }
 48         //Floyd算法计算任意两点之间的最短路径
 49         for (int k = 0; k < graph_size; k++)
 50             for (int v = 0; v < graph_size; v++)
 51                 for (int w = 0; w < graph_size; w++)
 52                     if (shortest_dis[v][k] + shortest_dis[k][w] < shortest_dis[v][w])
 53                     {
 54                         shortest_dis[v][w] = shortest_dis[v][k] + shortest_dis[k][w];
 55                         trace_node[v][w] = trace_node[v][k];
 56                     }
 57         cout << "这是最短路径数组:" << endl;
 58         for (int i = 0; i < graph_size; i++)
 59         {
 60             for (int j = 0; j < graph_size; j++)
 61                 cout << shortest_dis[i][j] << " ";
 62             cout << endl;
 63         }
 64         cout << "这是结点跟踪数组:" << endl;
 65         for (int i = 0; i < graph_size; i++)
 66         {
 67             for (int j = 0; j < graph_size; j++)
 68                 cout << trace_node[i][j] << " ";
 69             cout << endl;
 70         }
 71     }
 72     void shortest_path(int i, int j)
 73     {
 74         cout << "" << i << "" << j << "的最短路径长度为" << shortest_dis[i][j] << endl;
 75         cout << "路径为:" << endl;
 76         int k = trace_node[i][j];
 77         cout << i ;
 78         while (k != j)
 79         {
 80             cout << "->" << k;
 81             k = trace_node[k][j];//从起点出发,找到途经结点
 82         }
 83         cout << "->" << j << endl;
 84     }
 85     void connected(int v)//输出所有和v直达的结点
 86     {
 87         for (int i = 0; i < graph_size; i++)
 88         {
 89             if (adjacency[v][i] != 100 && adjacency[v][i] != 0)
 90                 cout << nodes[i] << " 距离为:" << adjacency[v][i] << ";" << endl;
 91         }
 92     }
 93     int BFS(int v,void (*visit)(Vertex &))
 94     {
 95         distance = 0;
 96         bool visited[graph_size] = { false };
 97         Vertex src = nodes[v];//找到选定的源点
 98         visited[v] = true;
 99         (*visit)(src);
100         for (int i = 0; i < graph_size; i++)
101         {
102             if (adjacency[v][i] != 100 && adjacency[v][i] != 0)//对相邻点进行深度优先遍历
103                 traverse(i, visited, visit);
104         }
105         return distance;
106     }
107 private:
108     int count;//结点数
109     int distance;//一条遍历路径总长
110     int adjacency[graph_size][graph_size];//存储权的邻接矩阵
111     Vertex nodes[graph_size];//存储结点内容的一维数组
112     int shortest_dis[graph_size][graph_size];//保存最短路径长度
113     int trace_node[graph_size][graph_size];//保存结点跟踪路径
114     void traverse(int v, bool visited[], void (*visit)(Vertex &))//辅助遍历函数
115     {
116         if (visited[v] == false)
117         {
118             (*visit)(nodes[v]);
119             visited[v] = true;
120             for (int i = 0; i < graph_size; i++)
121                 if (adjacency[v][i] != 100 && adjacency[v][i] != 0 && visited[i] == false)
122                 {
123                     traverse(i, visited, visit);//递归地进行深度优先遍历
124                     distance += adjacency[v][i];
125                 }
126                     
127         }
128     }
129 };
Digraph.h

学校类

  1 #include <fstream>
  2 #include <string>
  3 #include "Digraph.h"
  4 using namespace std;
  5 
  6 struct Place//地点定义
  7 {
  8     int number;
  9     string name;
 10     string introduction;
 11 
 12     Place(){}
 13     Place(int num,string nam,string intro):number(num),name(nam),introduction(intro){}
 14     void print()//显示此地点的信息
 15     {
 16         cout<<"---------------------------"<<endl;
 17         cout<<"编号:"<<number<<endl;
 18         cout<<"地点名:"<<name<<endl;
 19         cout<<"简介:"<<introduction<<endl;
 20         cout<<"---------------------------"<<endl;
 21     }
 22 };
 23 ostream& operator<<(ostream &os, Place &aPlace)//重载输出运算符
 24     {
 25         os << aPlace.number << ":" << aPlace.name;
 26         return os;
 27     }
 28 ofstream outFile;//输出流
 29 
 30 class School
 31 {
 32 private:
 33     int total;//总的地点数
 34     Digraph<Place,13> places_graph;
 35     void readFile(const char filename[20])//读文件
 36     {
 37         total = 0;
 38         ifstream inFile;
 39         inFile.open(filename);
 40         char trying;
 41         while(inFile.is_open() && !inFile.eof())
 42         {
 43             //先试探是否为结束符
 44             inFile >> trying;
 45             if (trying == #) break;
 46             else
 47             {
 48                 inFile.putback(trying);
 49                 int number;
 50                 inFile>>number;
 51                 string name;
 52                 inFile>>name;
 53                 string introduction;
 54                 inFile>>introduction;
 55                 Place aPlace=Place(number,name,introduction);
 56                 //aPlace.print();//显示这个地点的信息
 57                 places_graph.insert(aPlace);
 58                 total++;
 59             }            
 60         }
 61         for (int i = 0; i < 13; i++)//读入距离内容
 62             for (int j = 0; j < 13; j++)
 63             {
 64                 int dis;
 65                 inFile >> dis;
 66                 places_graph.distance_set(i, j, dis);
 67             }
 68         inFile.close();
 69         places_graph.calculate_path();//计算所有最短路径并存入数组
 70         cout << "学校共有" << total << "个地方"<<endl;
 71     }
 72     static void readPlace(Place &aPlace)
 73     {
 74         outFile<<aPlace.number<<endl;
 75         outFile<<aPlace.name<<endl;
 76         outFile<<aPlace.introduction<<endl;
 77     }
 78     static void print(Place &aPlace)//显示此地点的信息编号、名称
 79     {
 80         cout<<aPlace.number<<": "<<aPlace.name<<endl;
 81     }
 82     static void visit(Place &aPlace)
 83     {
 84         cout << "->" << aPlace.number << ":" << aPlace.name << endl;
 85     }
 86 public:
 87     School(const char filename[20])
 88     {
 89         readFile(filename);
 90     }
 91     void display()
 92     {
 93         cout<<"以下为学校的所有地点:"<<endl;
 94         places_graph.traverse(print);
 95     }
 96     void search()
 97     {
 98         cout<<"请输入要查询的地点编号:";
 99         int num;
100         cin>>num;
101         Place aPlace;
102         places_graph.search_vertex(num,aPlace);//查到要查的地点
103         cout<<"以下是这一地点的信息:"<<endl;
104         aPlace.print();
105     }
106     void path()
107     {
108         cout << "请输入想查询最短路径的两个地点的编号(如:5 7):";
109         int i, j;
110         cin >> i >> j;
111         places_graph.shortest_path(i, j);
112     }
113     void traverse()//深度优先遍历,输出路线
114     {
115         cout << "请输入源点的编号:";
116         int v;
117         cin >> v;
118         int distance;
119         distance = places_graph.BFS(v, visit);
120         cout << endl << "路径总长为:" << distance<<endl;
121     }
122     void reachable()
123     {
124         cout << "请输入源点的编号:";
125         int v;
126         cin >> v;
127         cout << "和地点" << v << "有直达路径的地点如下:" << endl;
128         places_graph.connected(v);
129     }
130 };

主函数流程图:

技术分享

运行截图:

技术分享技术分享技术分享技术分享技术分享

 

 附:测试用的文件School.txt内容

技术分享
0
前门
南门;车辆进出
1
教一楼
阶梯教室;英语教室
2
教二楼
普通教室
3
教三楼
实验室;办公室;阶梯教室
4
学一公寓
男生宿舍
5
学二公寓
男生宿舍
6
学三公寓
女生宿舍
7
学四公寓
男生宿舍
8
食堂
一层;二层;清真
9
水房
在食堂旁边
10
操场
300米一圈的跑道
11
图书馆
借阅部;自习室
12
后门
北门;取快递
#
  0   1   4   8   6 100 100  10 100   1 100  10 100
  1   0   3   4   5 100  10 100   1 100   1 100 100
  4   3   0  10   1   7 100   6 100  10 100 100   8
  8   4  10   0   2 100   3 100 100   6   5   9   7
  6   5   1   2   0   3   6   9 100   7   9   8   5
100 100   7 100   3   0 100   5 100   6   7   8   4
100  10 100   3   6 100   0   2   7   2   9  10   2
10  100   6 100   9   5   2   0   4 100   2   3   7
100   1 100 100 100 100   7   4   0  10   4   5   1
1   100  10   6   7   6   2 100  10   0   8   5   7
100   1 100   5   9   7   9   2   4   8   0   2   9
10  100 100   9   8   8   10  3   5   5   2   0 100
100 100   8   7   5   4   2   7   1   7   9  100  0
School.txt

  

 

用无向带权图实现校园导航系统

标签:

原文地址:http://www.cnblogs.com/helenawang/p/4430630.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!