zoukankan      html  css  js  c++  java
  • 用无向带权图实现校园导航系统

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

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

    用到的算法: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

      

  • 相关阅读:
    抓鱼社区
    DotNetTextBox V3.0 所见即所得编辑器控件Ver3.3.3 Free(免费版)
    Pet Shop 4.0系统
    北大青鸟PPT/ Net学习课件/asp.net,AJAX,ADO.net视频教程
    [开源]ASP.NET通用权限管理系统(FrameWork) 1.0.1 Release
    sql isnull函数
    几种常见算法的介绍及复杂度分析(转)
    ajaxpro配置与使用
    C#对图片的几种简单处理
    [你必须知道的.NET] 开篇有益
  • 原文地址:https://www.cnblogs.com/helenawang/p/4430630.html
Copyright © 2011-2022 走看看