数据结构课程设计——校园导游系统(图)

2019/11/26 18:45
阅读数 79

数据结构课程设计——校园导游系统

主要的任务为两个:

  1. 求两点间最短路径。(迪杰斯特拉算法)
  2. 求两点间简单路径。(dfs)

难度不大。部分有注释。

//先是MGraph中的主要算法实现
#ifndef MGRAPH_H_INCLUDED
#define MGRAPH_H_INCLUDED

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

#define MAX_VEX 20
#define MAX_NUM 32767

typedef struct vex
{
    string name;
    string info;
} vex, *vexptr;


//图的邻接矩阵存储表示
typedef struct
{
    vex vexs[MAX_VEX];                    //顶点表
    int arcs[MAX_VEX][MAX_VEX];        //邻接矩阵
    int vexnum, arcnum;                 //图的当前点数和边数
} MGraph;


//获取顶点位置:若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息
int LocateVex(MGraph &G, string u)
{
    int index = -1;                         //原始下标,没找到元素返回-1
    for(int i = 0; i < G.vexnum; i++)      //遍历顶点数组
    {
        if(u == G.vexs[i].name)
        {
            index = i;                      //记录元素下标
        }
    }
    return index;                           //返回下标
}

void MapOfHdu()
{
    cout<<"==============简略地图(地点括号内为在顶点表中的下标)============="<<endl;
    cout<<"八号楼(8)"<<endl;
    cout<<"                                                      学生活动中心(10) "<<endl;
    cout<<"                                 图书馆(9)"<<endl;
    cout<<""<<endl;
    cout<<"       体育馆(5)"<<endl;
    cout<<""<<endl;
    cout<<"                    六号楼(6)             七号楼(7)              "<<endl;
    cout<<""<<endl;
    cout<<"                    四号楼(4)"<<endl;
    cout<<"                                          三号楼(3)"<<endl;
    cout<<"                    二号楼(2)"<<endl;
    cout<<"                                          一号楼(1)"<<endl;
    cout<<"============================南大门(0)============================"<<endl;
}


int CreateMap(MGraph &G)
{
    G.vexnum = 11;//顶点数
    G.arcnum = 17;//边数

    //初始化邻接矩阵,所有边的权值置INF(MAX_NUM)
    for(int i = 0; i < G.vexnum; ++i)
    {
        for(int j = 0; j < G.vexnum; ++j)
        {
            G.arcs[i][j] = MAX_NUM;
        }
    }

    G.vexs[0].name = "南大门";
    G.vexs[0].info = "南大门为学校正大门";
    G.vexs[1].name = "一号楼";
    G.vexs[1].info = "信仁楼";
    G.vexs[2].name = "二号楼";
    G.vexs[2].info = "信义楼";
    G.vexs[3].name = "三号楼";
    G.vexs[3].info = "信礼楼";
    G.vexs[4].name = "四号楼";
    G.vexs[4].info = "在建";
    G.vexs[5].name = "体育馆";
    G.vexs[5].info = "体育馆简介";
    G.vexs[6].name = "六号楼";
    G.vexs[6].info = "信诚楼";
    G.vexs[7].name = "七号楼";
    G.vexs[7].info = "信博楼";
    G.vexs[8].name = "八号楼";
    G.vexs[8].info = "信远楼";
    G.vexs[9].name = "图书馆";
    G.vexs[9].info = "图书馆简介";
    G.vexs[10].name = "学生活动中心";
    G.vexs[10].info = "学生活动中心简介";


    //初始化各边权值
    G.arcs[0][1] = 100;
    G.arcs[0][2] = 100;
    G.arcs[0][3] = 300;
    G.arcs[1][2] = 250;
    G.arcs[1][3] = 100;
    G.arcs[2][3] = 250;
    G.arcs[3][4] = 350;
    G.arcs[3][8] = 1000;
    G.arcs[4][5] = 500;
    G.arcs[4][6] = 300;
    G.arcs[4][8] = 800;
    G.arcs[5][6] = 200;
    G.arcs[5][10] = 900;
    G.arcs[7][8] = 850;
    G.arcs[7][9] = 150;
    G.arcs[7][10] = 250;
    G.arcs[9][10] = 150;

    G.arcs[1][0] = 100;
    G.arcs[2][0] = 100;
    G.arcs[3][0] = 300;
    G.arcs[2][1] = 250;
    G.arcs[3][1] = 100;
    G.arcs[3][2] = 250;
    G.arcs[4][3] = 350;
    G.arcs[8][3] = 1000;
    G.arcs[5][4] = 500;
    G.arcs[6][4] = 300;
    G.arcs[8][4] = 800;
    G.arcs[6][5] = 200;
    G.arcs[10][5] = 900;
    G.arcs[8][7] = 850;
    G.arcs[9][7] = 150;
    G.arcs[10][7] = 250;
    G.arcs[10][9] = 150;

    return 1;
}

//景点介绍
int GetInfo(MGraph &G, string u)
{
    for(int i = 0; i < G.vexnum; i++)
    {
        if(G.vexs[i].name == u)
        {
            cout<<"有关该景点的信息是:";
            cout<< G.vexs[i].info << endl;
            return 1;
        }
    }
    cout << "未查询到此景点!" << endl;
    return 0;
}

int GetDistance(MGraph &G, string u1,string u2)
{
    int id1,id2;
    id1=LocateVex(G,u1);
    id2=LocateVex(G,u2);
    return G.arcs[id1][id2]<MAX_NUM?G.arcs[id1][id2]:-1;
}

void Dijkstra(MGraph G,int v,int dist[],int path[])
{
    int Set[MAX_VEX];
    int Min,u;
    //对数组进行初始化//
    for(int i=0; i<G.vexnum; i++)
    {
        dist[i]=G.arcs[v][i];
        Set[i]=0;
        if(G.arcs[v][i]<MAX_NUM)
        {
            path[i]=v;
        }
        else
        {
            path[i]=-1;
        }
        Set[v]=1;
        path[v]=-1;
    }
    //关键操作//
    for(int i=0; i<G.arcnum-1; i++)
    {
        Min=MAX_NUM;
        //循环每次从剩余顶点中挑出一个顶点,它是S集通往所有顶点的路径长度最小的那个//
        for(int j=0; j<G.arcnum; j++)
        {
            if(Set[j]==0&&dist[j]<Min)
            {
                u=j;
                Min=dist[j];
            }
        }
        Set[u]=1;//将选出的顶点并入最短路径中
        //循环以刚并入的顶点对通往剩余顶点的所有路径进行检测//
        for(int j=0; j<G.arcnum; j++)
        {
            //if判断顶点U的加入是否会出现通往顶点j的更短的路径,如果出现,则改变原来路径及其长度,否则不变//
            if(Set[j]==0&&dist[u]+G.arcs[u][j]<dist[j])
            {
                dist[j]=dist[u]+G.arcs[u][j];
                path[j]=u;
            }
        }
    }
    //算法结束后,dist[]中存放初始顶点v到其余顶点的最短路径长度,path[]中存放v到其余顶点的最短路径//

}


void printPath(int path[],int a)
{
    //path实际上是一颗双亲存储结构的树,故需要栈来将其逆序输出//
    int Stack[MAX_VEX];
    int top=-1;

    while(path[a]!=-1)
    {
        Stack[++top]=a;
        a=path[a];
    }
    Stack[++top]=a;
    while(top!=-1)
    {
        cout<<Stack[top--]<<" ";
    }
    cout<<endl;
}

int visited[MAX_VEX]= {0};
int DFSpath[MAX_VEX]= {0};
int DFStop=-1;

void DFS(MGraph & G,int v,int e)
{
    visited[v]=1;
    DFSpath[++DFStop]=v;

    for(int i=0; i<G.vexnum; i++)
    {
        if(v==e)
        {
            for(int j=0; j<=DFStop; j++)
            {
                cout<<DFSpath[j]<<" ";
            }
            cout<<endl;
            visited[v]=0;
            DFStop--;
            break;
        }

        if((G.arcs[v][i]<MAX_NUM)&&(!visited[i]))
        {
            DFS(G,i,e);
        }

        if(i==G.vexnum-1)//准备回溯前先处理栈和当前节点状态
        {
            DFStop--;
            visited[v]=0;
        }

    }
}
#endif // MGRAPH_H_INCLUDED

之后是主程序实现。

#include <iostream>
#include "MGraph.h"

using namespace std;

void menu()
{
        cout << "----------------------欢迎咨询校园导游系统---------------------- "<< endl;
        cout << "--------------------请在屏幕上输入相应的数字--------------------- "<< endl;
        cout << "                  【1】.  查看地图                               " << endl;
        cout << "                  【2】.  信息查询                               " << endl;
        cout << "                  【3】.  最短路径查询                           " << endl;
        cout << "                  【4】.  简单路径查询                           " << endl;
        cout << "                  【5】.  退出程序                               " << endl;
        cout<< "-------------------------------------------------------------------" << endl;
}

int main(){
    MGraph G;
    int m;
    string b;
    CreateMap(G);

    while(1){
        menu();
        cin>> m;
        switch(m){
            case 1:
            {
                MapOfHdu();
                system("pause");
                system("cls");
                break;
            }
            case 2:
            {
                MapOfHdu();
                cout << "请输入要查询的位置名称:";
                cin>> b;
                GetInfo(G, b);
                system("pause");
                system("cls");
                break;
            }
            case 3:
            {
                MapOfHdu();
                string v1, v2;
                int v1i,v2i;
                int dist[MAX_VEX],path[MAX_VEX];
                cout << "请输入起点和终点:(输入名称并以空格间隔)";
                cin>> v1 >> v2;
                cout << v1 << "到" << v2 << "的最短路径长为:";
                v1i=LocateVex(G,v1);
                v2i=LocateVex(G,v2);
                Dijkstra(G,v1i,dist,path);
                cout<<dist[v2i]<<endl;
                cout << v1 << "到" << v2 << "的最短路径为:";
                printPath(path,v2i);
                cout<< endl;

                system("pause");
                system("cls");
                break;
            }
            case 4:
            {
                MapOfHdu();
                string v1, v2;
                int v1i,v2i;
                cout << "请输入起点和终点:(输入名称并以空格间隔)";
                cin>> v1 >> v2;
                cout << v1 << "到" << v2 << "的所有简单路径为:"<<endl;
                v1i=LocateVex(G,v1);
                v2i=LocateVex(G,v2);
                DFS(G,v1i,v2i);
                system("pause");
                system("cls");
                break;
            }

            case 5:
                return 0;
        }
    }
}

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部