烟台大学数据结构校园导航系统

烟台大学数据结构课程设计                            题目14校园导航

 

14、校园导航问题

【问题描述】

以我校为例,设计一个校园导游程序,主要为来访的客人提供信息查询。

【基本要求】

提供至少5个景点的校园导游咨询(包括景点介绍、景点间距离等)。

本程序的目的是为来客提供路径咨询和景点查询(根据用户指定的始点和终点输出相应最短简单路径或者输出用户指定景点的详细信息);系统管理员又可根据实际情况对导游图进行修改,删除路径或景点。

选取九个大家熟悉的景点,抽象成一张带权无向图(如图所示)。以图中顶点表示景点,存放景点名称、代号等信息;以边表示路径,边上的权值表示两地的距离,为此图选择适当的数据结构:

 

本演示程序采用C语言编写,完成了无向图的建立和其他操作:

① 输入的形式和输入值的范围:主函数中调用图表建立函数之后,通过输入1到6不同的阿拉伯数字进行功能选择;在查找景点详细信息操作时需要输入景点的的序号;在求路径函数中,也是输入对应景点序号值;在删除路线函数里,输入构成边的两个景点的序号对;。在所有输入操作中,输入的值都是整数

② 输出的形式:菜单函数,输出功能菜单目录;查找函数信息操作,输出景点序号,名称,还有详细介绍;求最短路径函数,输出路线经过的顶点和路线的长度!删除函数,当删除成功后会输出删除成功;求删除操作后显示删除的元素的值。

③ 程序所能达到的功能:完成无向带权图的生成(通过建立顶点数组和邻接矩阵)、通过选择菜单进行不同操作,查看景点信息、求景点间最短路径、删除景点或路线。

④ 测试数据:

A. 查看景点详细信息操作中输入3

B. 查询最短路径操作中输入3,5

C. 删除操作中先后输入1(删除景点),2)(删除边)

D. 删除景点操作中输入1

E. 删除边操作中输入1,5

F. 查看一个景点到其他景点所有路线输入1 

 

 

 

 

 

//顶点为0-8//顶点为0-8//顶点为0-8//顶点为0-8//顶点为0-8//顶点为0-8//顶点为0-8

#include<bits/stdc++.h>
#include<iostream>
#define inf 0xfffffff
#define MAXV 1000
#define sizes 9
using namespace std;
int v;
int x,y;
int m=1;
int maps[sizes][sizes]={
{0,inf,100,200,100,inf,inf,inf,inf},
{inf,0,500,inf,200,inf,inf,inf,inf},
{100,500,0,inf,inf,inf,inf,500,inf},
{200,inf,inf,0,inf,inf,inf,inf,200},
{100,200,inf,inf,0,inf,inf,inf,inf},
{inf,inf,inf,inf,inf,0,100,inf,500},
{inf,inf,inf,inf,inf,100,0,100,inf},
{inf,inf,500,inf,inf,inf,100,0,700},
{inf,inf,inf,200,inf,500,inf,700,0},
};
int mapkey[sizes][sizes];
int dis[100];
int judge;
void dfs(int x,int path[],int d)
{
    d++;
    path[d]=x;
    dis[x]=1;
    if(x==y&&d>=0)
    {
        for(int i=0;i<=d;i++)
        {
            printf("%d ",path[i]);
        }
        cout<<endl;
    }
    for(int i=0;i<sizes;i++)
    {
        if(dis[i]==0&&maps[x][i]!=inf&&x!=i)
        {
            dfs(i,path,d);
            dis[i]=0;
        }
    }
}
void chakan()
{
    int n;
    cout<<"欢迎来到查看函数\n";
    cout<<"请输入想要查看的标记序号\n";
    cin>>n;
    if(n==1)
        cout<<"宿舍"<<endl;
    else if(n==2)
        cout<<"图书馆"<<endl;
    else if(n==3)
        cout<<"办公楼"<<endl;
    else if(n==4)
        cout<<"理学院"<<endl;
    else if(n==5)
        cout<<"文学院"<<endl;
    else if(n==6)
        cout<<"食堂"<<endl;
    else if(n==7)
        cout<<"工程实训中心"<<endl;
    else if(n==8)
        cout<<"计算机中心"<<endl;
    else if(n==9)
        cout<<"校史馆"<<endl;
    system("pause");
    exit(0);
}
void Dispath(int dist[],int path[],int S[])//输出从顶点v出发的所有最短路径
{
    int i,j,k;
int apath[MAXV],d;//存放一条最短路径(逆向)及其顶点个数
cout<<"请输入另一个节点"<<endl;
cin>>i;
while(i==v)
    {
        cout<<"非法输入,请重新操作"<<endl;
        cin>>i;
    }
if(S[i]==1&&i!=v)
    {
        printf("  从顶点%d到顶点%d的路径长度为:%d\t路径为:",v,i,dist[i]);
        d=0;
        apath[d]=i; //添加路径上的终点
        k=path[i];
        if(k==-1) //没有路径的情况
            printf("无路径\n");
        else //存在路径时输出该路径
        {
            while(k!=v)
            {
                d++;
                apath[d]=k;
                k=path[k];
            }
            d++;
            apath[d]=v; //添加路径上的起点
            printf("%d",apath[d]); //先输出起点
            for(j=d-1;j>=0;j--) //再输出其他顶点
                printf(",%d",apath[j]);
            printf("\n");
        }
    }
}
void dijkstra()
{
    cout<<"欢迎来到查询所有路线函数\n";
    cout<<"请输入起点\n";
    cin>>v;
    int dist[MAXV],path[MAXV];
int S[MAXV]; //S[i]=1表示顶点i在S中, S[i]=0表示顶点i在U中
int Mindis,i,j,u;
for (i=0;i<sizes;i++)
{
   dist[i]=maps[v][i];//距离初始化
S[i]=0; //S[]置空
if (maps[v][i]<inf)//路径初始化
path[i]=v; //顶点v到顶点i有边时,置顶点i的前一个顶点为v
else
path[i]=-1; //顶点v到顶点i没边时,置顶点i的前一个顶点为-1
}
S[v]=1;
path[v]=0; //源点编号v放入S中
for(i=0;i<sizes-1;i++)//循环直到所有顶点的最短路径都求出
{
   Mindis=inf;//Mindis置最大长度初值
for(j=0;j<sizes;j++)//选取不在S中(即U中)且具有最小最短路径长度的顶点u
if(S[j]==0&&dist[j]<Mindis)
{
   u=j;
Mindis=dist[j];
}
S[u]=1; //顶点u加入S中
for(j=0;j<sizes;j++)//修改不在S中(即U中)的顶点的最短路径
        {
            if(S[j]==0)
            {
                if(maps[u][j]<inf&&dist[u]+maps[u][j]<dist[j])
{
   dist[j]=dist[u]+maps[u][j];
path[j]=u;
}
            }
        }
}
Dispath(dist,path,S);//输出最短路径
}
void deletes()
{
    int num;
    int node;
    int node1,node2;
    cout<<"欢迎来到删除函数"<<endl;
    cout<<"1.删除节点  2.删除边  请输入你要进行的操作的序号"<<endl;
    scanf("%d",&num);
    if(num==1)
    {
        cout<<"请输入您要删除的节点"<<endl;
        cin>>node;
        for(int i=0;i<sizes;i++)
        {
            if(node==i)
            {
                maps[i][node]=0;
            }
            else
            {
                maps[i][node]=inf;
                maps[node][i]=inf;
            }
        }
    }
    else if(num==2)
    {
        cout<<"请输入您要删除的边"<<endl;
        cin>>node1>>node2;
        while(node1==node2)
        {
            cout<<"非法输入"<<endl;
            cout<<"请输入您要删除的边"<<endl;
            cin>>node1>>node2;
        }
        maps[node1][node2]=inf;
        maps[node2][node1]=inf;
    }
    else
    {
        cout<<"非法输入"<<endl;
        deletes();
    }
    cout<<"进行检查打印"<<endl;
    for(int i=0;i<sizes;i++)
    {
        for(int j=0;j<sizes;j++)
        {
            cout<<maps[i][j]<<" ";
        }
        cout<<endl;
    }
    system("pause");
    exit(0);
}
void panduan(int n)
{
    int path[100];
    int d=-1;
    switch(n)
    {
        case 1:
            chakan();
            break;
        case 2:
            dijkstra();
            break;
        case 3:
            deletes();
            break;
        case 4:
            cout<<"请输入你要查找的起点和终点"<<endl;
            scanf("%d%d",&x,&y);
            path[0]=x;
            cout<<"欢迎来到查看函数"<<endl;
            dfs(x,path,d);
            break;
        default:
            printf("请重新输入输入选择项目序号(1-4):\n");
            cin>>n;
            panduan(n);
    }
    return;
}
int main()
{
    system("color 0E");
    int x;
    printf("—————————————————欢迎来到校园导航———————————————————\n");
    printf("——————————————————————菜单项————————————————————————\n");
    printf("—————————————————1.查看景点详细信息——————————————————\n");
    printf("—————————————————2.查询最短路径———————————————————————\n");
    printf("——————————————————3.删除操作———————————————————————————\n");
    printf("———————————————4.查看某景点到其他景点路线——————————————\n");
    printf("输入选择项目序号(1-4):\n");
    cin>>judge;
    panduan(judge);
    return 0;
}

  • 5
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
校园导航系统是一个基于数据结构的C语言程序,主要功能是实现校园地图的导航和最短路径的输出。该程序需要读者自己进行一些景点介绍和校园介绍的存储路径的更改,才能成功实现导航功能。该程序使用了图的数据结构,通过Dijkstra算法实现最短路径的计算。如果您想了解更多关于该程序的实现细节,可以参考引用中的文章。 以下是一个简单的Dijkstra算法的实现,用于计算从起点到终点的最短路径: ```c #include <stdio.h> #include <limits.h> #define V 9 int minDistance(int dist[], bool sptSet[]) { int min = INT_MAX, min_index; for (int v = 0; v < V; v++) if (sptSet[v] == false && dist[v] <= min) min = dist[v], min_index = v; return min_index; } void printPath(int parent[], int j) { if (parent[j] == -1) return; printPath(parent, parent[j]); printf("%d ", j); } void printSolution(int dist[], int n, int parent[], int src, int dest) { printf("Shortest path from %d to %d:\n", src, dest); printf("Vertex Distance Path\n"); for (int i = 0; i < V; i++) { if (i == dest) { printf("%d \t\t %d\t\t%d ", i, dist[i], src); printPath(parent, i); } } } void dijkstra(int graph[V][V], int src, int dest) { int dist[V]; bool sptSet[V]; int parent[V]; for (int i = 0; i < V; i++) { parent[src] = -1; dist[i] = INT_MAX; sptSet[i] = false; } dist[src] = 0; for (int count = 0; count < V - 1; count++) { int u = minDistance(dist, sptSet); sptSet[u] = true; for (int v = 0; v < V; v++) { if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v]) { parent[v] = u; dist[v] = dist[u] + graph[u][v]; } } } printSolution(dist, V, parent, src, dest); } int main() { int graph[V][V] = {{0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0}}; dijkstra(graph, 0, 8); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幼儿园小班班长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值