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

来源:互联网 发布:阿里云投诉电话 编辑:程序博客网 时间: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);    }};

主程序流程图:
主函数

运行截图:
12345

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

#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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 法宣在线出现在其他地方登陆怎么办 QQ被冻结又不知道申诉资料怎么办 开通优酷会员了再开酷喵会员怎么办 考的不好时别人问你多少分时怎么办 订了产品一直收不到货怎么办 微信零钱提现忘记密码怎么办 微信里面的零钱忘记密码怎么办 微信的零钱密码丢了怎么办 微信公众号被屏蔽了所有功能怎么办 刚开淘宝店没信誉要怎么办 如果发现货品有问题商家不换怎么办 文件夹里面的图片怎么拖不动怎么办 网赌系统维护审核就不给提款怎么办 客户说我卖的东西是假货怎么办 微信小程序第三方平台倒闭了怎么办 金立手机锁屏密码忘了怎么办 不知道微信账号的公众号密码怎么办 微信公众号充话费充错号码怎么办 蜻蜓商城三天免流业务退不了怎么办 日上免税店提货日期写错了怎么办 微信公众平台账号名密码忘了怎么办 有人扬言要搞垮我的店铺怎么办 招行信用卡签到积分未领取怎么办 怎么办照片发送到邮微信箱里去 苹果手机备忘录没刪除就没了怎么办 因恶意刷公众号而被微信封号怎么办 禁停路段发生剐蹭怎么办办 新三板公司退市了 小股东怎么办? 爱用商城发货没有物流信息怎么办 拼多多的快递的运单号发错了怎么办 追光娱乐账号被别人盗用了怎么办啊 用鲁大师检测硬盘出现损坏怎么办 客户拖款迟迟不给给怎么办 百度云盘文件密码忘记了怎么办 用来注册亚马逊的公司注销了怎么办 亚马逊中国卖家太多美国卖家怎么办 付款了!卖家不想卖了怎么办? 手机通讯录同步助手密码忘了怎么办 毕业生学位信息照片上传错了怎么办 报名计算机二级照片上传很慢怎么办 网上报名时照片上传错了怎么办