c++数据结构--图综合应用实验——校院导航

实验内容:

面向学校,构建一个校院导游软件。用无向图表示所在学校的校院景点平面图,图中顶点表示主要景点,存放景点的编号、名称、简介等信息,图中边表示景点之间的道路,存放路径距离等信息。该软件具有以下基本功能,学生可自行扩展功能。
1)查询各景点的详细信息;
2)查询图中任意两个景点之间的所有可能路径;
3)查新图中任意两个景点之间的最短路径;
4)增加、删除、更新景点与道路信息

实验步骤:

(1)按照实验要求编写代码,构造导游软件系统。
(2)输入验收用例,验证其输出结果。

#include <iostream>
#include<string.h>
using namespace std;
#define MVNum 100
#define MAXDIS 368789

typedef struct ArcNode
{
    double distance;
    ArcNode *nextarc;
    int adjvex;
};
int *visit;
typedef struct VNode
{
    int number;
    string name;
    string resume;
    ArcNode *firstarc;
} VNode,AdjList[MVNum];
struct road
{
    int startPoint;
    int endPoint;
    double distance;
};

struct AGraph
{
    AdjList adjlist;
    double adjmatrix[MVNum][MVNum];
    int vexnum,arcnum;
};

int LocateVex(AGraph G,int v)
{
    for(int i =0; i<G.vexnum; i++)
    {
        if(G.adjlist[i].number==v) return i;
    }
    return -1;
}

void createvisit(int* &visit,int vexnum)
{
    visit = new int[vexnum];
    for(int i = 0; i < vexnum; i++)
    {
        visit[i] = 0;
    }
}

//构建无向图的邻接表
void CreateUDG(AGraph &G)
{
    G.vexnum=7;
    G.arcnum=10;
    createvisit(visit,G.vexnum);
    G.adjlist[0].number=0;
    G.adjlist[0].name="材料重点实验室";
    G.adjlist[0].resume="国家重点实验室";
    G.adjlist[0].firstarc=NULL;
    G.adjlist[1].number=1;
    G.adjlist[1].name="计算机学院";
    G.adjlist[1].resume="计算机上课的地方";
    G.adjlist[1].firstarc=NULL;
    G.adjlist[2].number=2;
    G.adjlist[2].name="志义体育场";
    G.adjlist[2].resume="运动会举办的地方";
    G.adjlist[2].firstarc=NULL;
    G.adjlist[3].number=3;
    G.adjlist[3].name="图书馆";
    G.adjlist[3].resume="河南存储书最多的地方";
    G.adjlist[3].firstarc=NULL;
    G.adjlist[4].number=4;
    G.adjlist[4].name="综合教学楼";
    G.adjlist[4].resume="学校主要上课的地方";
    G.adjlist[4].firstarc=NULL;
    G.adjlist[5].number=5;
    G.adjlist[5].name="物理学院";
    G.adjlist[5].resume="全校物理实验的上课地方";
    G.adjlist[5].firstarc=NULL;
    G.adjlist[6].number=6;
    G.adjlist[6].name="创业中心";
    G.adjlist[6].resume="最受学生喜欢的地方";
    G.adjlist[6].firstarc=NULL;
    //初始化邻接矩阵
    for (int i = 0; i<G.vexnum; i++)
    {
        for(int j = 0; j<G.vexnum; j++)
        {
            G.adjmatrix[i][j]=MAXDIS;
            //  if(i==j) G.adjmatrix[i][j]=0;
        }
    }
    //road1用于最初的图形初始化
    road road1[] = {{0,1,30},{1,3,10},{1,2,20},{1,4,10},{3,5,40},{3,4,5},{4,5,30},{2,4,30},{4,6,5},{5,6,50}};
    for(int k=0; k<G.arcnum; k++)
    {
        int number1,number2;
        double weight;
        number1 = road1[k].startPoint;
        number2 = road1[k].endPoint;
        weight=road1[k].distance;
        //将景点编号转为下标
        int i = LocateVex(G,number1);
        int j = LocateVex(G,number2);
        G.adjmatrix[i][j]=weight;
        G.adjmatrix[j][i]=weight;

        ArcNode *p1 = new ArcNode;
        p1->adjvex =j;
        p1->distance=weight;
        p1->nextarc = G.adjlist[i].firstarc;
        G.adjlist[i].firstarc=p1;

        ArcNode *p2 = new ArcNode;
        p2->distance=weight;
        p2->adjvex=i;
        p2->nextarc=G.adjlist[j].firstarc;
        G.adjlist[j].firstarc=p2;
    }
}
//该算法使用前需要设置一个visit数组,且全部为0,vi是起点,vj是终点
void FindPath(AGraph g,int vi,int vj,int path[],int d)
{
    ArcNode *p;
    visit[vi]=1;
    path[++d]=vi;
    if(vi==vj)
    {
        for(int i = 0; i<=d; i++)
        {
            cout << g.adjlist[path[i]].name<<" ";
        }
        cout << endl;
    }
    p=g.adjlist[vi].firstarc;
    while(p)
    {
        if(visit[p->adjvex]==0) FindPath(g,p->adjvex,vj,path,d);
        p = p->nextarc;
    }
    visit[vi]=0;
}

void Floyd(AGraph g,int path[MVNum][MVNum],int map[MVNum][MVNum])
{
    int n = g.vexnum;
    for(int i=1; i<=g.vexnum; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i==j)
                map[i][j]=0;
            else
                map[i][j]=MAXDIS;
        }
    }

    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(g.adjmatrix[i][j]!=MAXDIS)
            {
                map[i+1][j+1]=g.adjmatrix[i][j];
                map[j+1][i+1]=g.adjmatrix[i][j];
                path[i+1][j+1]=j+1;
            }
        }
    }
    //计算最短距离
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                if(map[i][k]+map[k][j]<map[i][j])
                {
                    map[i][j]=map[i][k]+map[k][j];
                    path[i][j]=path[i][k];
                }
    int v1,v2,z;
    cout<<"输入两个景点编号,输出最短路径"<<endl;
    cin>>v1>>v2;
    v1=LocateVex(g,v1);
    v2=LocateVex(g,v2);
    if(v1==-1||v2==-1) return;
    v1=v1+1;
    v2=v2+1;
    z=path[v1][v2];
    cout<<g.adjlist[v1-1].name;
    while(z!=v2)
    {
        cout<<"->"<<g.adjlist[z-1].name;
        z=path[z][v2];
    }
    cout<<"->"<<g.adjlist[v2-1].name;
}

void addV(AGraph &g,int n,int vi,int distance){
    cout << "请输入增加顶点的名称以及简介:";
    //邻接表增加
    cin >>g.adjlist[g.vexnum].name;
    cin >> g.adjlist[g.vexnum].resume;
    g.adjlist[g.vexnum].firstarc=NULL;
    g.adjlist[g.vexnum].number=g.adjlist[g.vexnum-1].number+1;
    g.vexnum=g.vexnum+1;//景点数+1
    //边表增加
    cout << endl<<"请输入景点的道路数目:";
    cin >> n;
    g.arcnum=g.arcnum+n;//边数+n
    cout << endl<<"请输入每条道路以该景点为起点所能到达的景点编号以及距离:"<<endl;
    //邻接矩阵初始化
    for(int i = 0; i<g.vexnum; i++)
    {
        g.adjmatrix[g.vexnum-1][i]=MAXDIS;
        g.adjmatrix[i][g.vexnum-1]=MAXDIS;
    }
    //创建边
    for(int i=0; i<n; i++)
    {
        cin >> vi >> distance;
        ArcNode *p1 = new ArcNode;
        p1->adjvex =vi;
        p1->distance=distance;
        p1->nextarc = g.adjlist[g.vexnum-1].firstarc;
        g.adjlist[g.vexnum-1].firstarc=p1;
        g.adjmatrix[g.vexnum-1][vi]=distance;
        g.adjmatrix[vi][g.vexnum-1]=distance;
        ArcNode *p2 = new ArcNode;
        p2->distance=distance;
        p2->adjvex=g.vexnum-1;
        p2->nextarc=g.adjlist[vi].firstarc;
        g.adjlist[vi].firstarc=p2;
    }
    //删除景点
}

void deleteV(int vi,AGraph &g){
    //修改邻接矩阵
    for(int i=vi+1; i<g.vexnum; i++)
    {
        for(int j=0; j<g.vexnum; j++)
        {
            g.adjmatrix[i-1][j]=g.adjmatrix[i][j];
        }
        for(int j=0; j<g.vexnum; j++)
        {
            g.adjmatrix[j][i-1]=g.adjmatrix[j][i];
        }
    }
    //修改邻接表
    for(int i=0; i<g.vexnum; i++)
    {
        //边指针
        ArcNode *p=g.adjlist[i].firstarc;
        //一条边的处理情况
        if(p->nextarc==NULL)
        {
            if(p->adjvex==vi)
            {
                g.adjlist[i].firstarc=NULL;
                g.arcnum=g.arcnum-1;
            }
        }
        //没有边
        else if(p==NULL) continue;
        //多条边
        else
        {
            //如果是首元结点
            if(p->adjvex==vi)
            {
                g.adjlist[i].firstarc=p->nextarc;
                g.arcnum=g.arcnum-1;
                continue;
            }
            //不是首元结点
            while(p->nextarc&&p->nextarc->adjvex!=vi)
            {
                p=p->nextarc;
            }
            if(p->nextarc)
            {
                p->nextarc=p->nextarc->nextarc;
                g.arcnum=g.arcnum-1;
            }
        }
    }
    for(int i=vi; i<g.vexnum-1; i++)
    {
        g.adjlist[i]=g.adjlist[i+1];
    }
    g.vexnum=g.vexnum-1;
}

void show(AGraph g){
    for(int i = 0; i <g.vexnum; i++)
    {
        cout << "编号:"<<g.adjlist[i].number<<"\t名称:"<<g.adjlist[i].name<<"\t简介:"<<g.adjlist[i].resume<<endl;
    }
}

void addPath(AGraph &g,int vi,int vj,int distance){
    cout << "请输入该路径长度:"<<endl;
    cin >> distance;
    g.adjmatrix[vi][vj]=distance;
    g.adjmatrix[vj][vi]=distance;

    ArcNode *p1 = new ArcNode;
    p1->adjvex =vj;
    p1->distance=distance;
    p1->nextarc = g.adjlist[vi].firstarc;
    g.adjlist[vi].firstarc=p1;

    ArcNode *p2 = new ArcNode;
    p2->distance=distance;
    p2->adjvex=vi;
    p2->nextarc=g.adjlist[vj].firstarc;
    g.adjlist[vj].firstarc=p2;
    g.arcnum=g.arcnum+1;
}

void alterV(int vi,AGraph &g){
    cout << "请输入要修改的景点编号:";
    cin >> vi;
    vi = LocateVex(g,vi);
    cout << "请输入修改后的景点名称以及简介:";
    cin >> g.adjlist[vi].name;
    cin >> g.adjlist[vi].resume;
}

void deletePath(AGraph &g,int vi,int vj){
            g.adjmatrix[vi][vj]=MAXDIS;
            g.adjmatrix[vj][vi]=MAXDIS;
            ArcNode *p=g.adjlist[vi].firstarc;
            //一条边的处理情况
            if(p->nextarc==NULL)
            {
                if(p->adjvex==vj)
                {
                    g.adjlist[vi].firstarc=NULL;
                    g.arcnum=g.arcnum-1;
                }
            }
            //多条边
            else
            {
                //如果是首元结点
                if(p->adjvex==vj)
                {
                    g.adjlist[vi].firstarc=p->nextarc;
                    g.arcnum=g.arcnum-1;
                }
                //不是首元结点
                while(p->nextarc&&p->nextarc->adjvex!=vj)
                {
                    p=p->nextarc;
                }
                if(p->nextarc)
                {
                    p->nextarc=p->nextarc->nextarc;
                    g.arcnum=g.arcnum-1;
                }
            }
            p=g.adjlist[vj].firstarc;
            //一条边的处理情况
            if(p->nextarc==NULL)
            {
                if(p->adjvex==vi)
                {
                    g.adjlist[vj].firstarc=NULL;
                    g.arcnum=g.arcnum-1;
                }
            }
            //多条边
            else
            {
                //如果是首元结点
                if(p->adjvex==vi)
                {
                    g.adjlist[vj].firstarc=p->nextarc;
                    g.arcnum=g.arcnum-1;
                }
                //不是首元结点
                while(p->nextarc&&p->nextarc->adjvex!=vi)
                {
                    p=p->nextarc;
                }
                if(p->nextarc)
                {
                    p->nextarc=p->nextarc->nextarc;
                    g.arcnum=g.arcnum-1;
                }
            }
}

void alterPath(AGraph &g,int distance,int vi,int vj){
    cout << "请输入修改后的路径长度"<<endl;
    cin >> distance;
    g.adjmatrix[vi][vj]=distance;
    g.adjmatrix[vj][vi]=distance;
    ArcNode *p=g.adjlist[vi].firstarc;
    while(p->adjvex!=vj) p=p->nextarc;
    p->distance=distance;
    p=g.adjlist[vj].firstarc;
    while(p->adjvex==vi) p=p->nextarc;
    p->distance=distance;
}

void home()
{
    cout <<" |   <河南大学校园导航>   |"<<endl;
    cout <<" |    1.校园景点          |"<<endl;
    cout <<" |    2.查询路径          |"<<endl;
    cout <<" |    3.最短路径          |"<<endl;
    cout <<" |    4.增加景点          |"<<endl;
    cout <<" |    5.删除景点          |"<<endl;
    cout <<" |    6.修改景点          |"<<endl;
    cout <<" |    7.增加路径          |"<<endl;
    cout <<" |    8.删除路径          |"<<endl;
    cout <<" |    9.修改路径          |"<<endl;
    cout <<" |    10.退出导航         |"<<endl;
}
int main()
{
    AGraph g;
    CreateUDG(g);
    int path[g.vexnum];
    int path1[MVNum][MVNum];
    int map[MVNum][MVNum];
    int vi,vj;
    int distance;
    int choice;
    int n;
    home();
    while(1)
    {
        cout << "请输入您的需求:";
        cin >> choice;
        switch(choice)
        {
        case 1:
            //查询各景点信息
            show(g);
            break;
        //查询任意路径
        case 2:
            cout << "请依次输入初始景点编号及终点景点编号:";
            cin >> vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            cout << endl;
            FindPath(g,vi,vj,path,-1);
            break;
        //最短路径
        case 3:
            Floyd(g,path1,map);
            cout << endl;
            break;
        //增加景点
        case 4:
            addV(g,n,vi,distance);
            break;
        case 5:
            cout << "请输入景点编号:";
            cin >> vi;
            vi = LocateVex(g,vi);
            if(vi==-1) break;
            deleteV(vi,g);
            break;
        //修改景点
        case 6:
            alterV(vi,g);
            break;
        //增加路径
        case 7:
        {
            cout << "请输入路径两端景点编号:"<<endl;
            cin >>vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            addPath(g,vi,vj,distance);
        }
            break;
        //删除路径
        case 8:
            cout << "请输入路径两端景点编号:"<<endl;
            cin >>vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            deletePath(g,vi,vj);
            break;
        case 9:
            cout << "请输入路径两端景点编号:"<<endl;
            cin >>vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            alterPath(g,distance,vi,vj);
            break;
        case 10:
            return 0;
            break;

            }
            cout <<endl;
    }
    return 0;
}

在这里插入图片描述

  • 18
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值