数据结构实践----财大导游图

     首先写主函数

#include<iostream>
#include <fstream>
#include"maps.h"
using namespace std;
char password[20];
typedef struct name {
    string sight;
    string data;
    int number;
}name;
typedef struct school {
    name vex[MAXSIZE];//名字
    int arcs[MAXSIZE][MAXSIZE];//距离
    int num;//景点个数
}school;
void add(school* G);//添加景点
bool change(school* G);//修改景点信息
bool addway(school* G);//新建景点路径
bool user2(school G);//导游图上单个景点的信息
void user3(school G);//导游图所有景点的信息
void Dispath(school G, int dist[], int path[], int S[], int v, int m);//输出最短路径
void Dijkstra(school G, int v, int m);//dijkstra算法求最短路径
int main() {
    ofstream fw;
    ifstream fr;
    fr.open("text.txt");            
    fr >> password;                          //从text.txt读入管理员密码
    fr.close();                     
    int i = 0;
    int n = 0;
    int m = 0;
    school G;     //创建结构体
    fr.open("text2.txt");            
    fr >> G.num;                          //从text2.txt读入景点个数
    fr.close();                     
    fr.open("text1.txt");//从taxt1.txt中读入景点数据
    for (int i = 1; i <= G.num; i++) {
        fr >> G.vex[i].number;
        fr >> G.vex[i].sight;
        fr >> G.vex[i].data;
    }
    fr.close();//关闭taxt1.txt
    fr.open("text3.txt");//从文档中读入景点之间的距离
    for (int i = 1; i <= G.num; i++) {
        for (int j = 1; j <= G.num; j++) {
            fr >> G.arcs[i][j];
        }
    }
    fr.close();
A://写入数据节点
    fw.open("text1.txt");//向taxt1.txt中写入景点数据
    for (int i = 1; i <= G.num; i++) {
        fw << G.vex[i].number;
        fw << " ";
        fw << G.vex[i].sight;
        fw << " ";
        fw << G.vex[i].data;
        fw << endl;
    }
    fw.close();
    fw.open("text2.txt");//向text2中写入景点个数
    fw << G.num;
    fw.close();
    fw.open("text3.txt");//向taxt3中写入景点之间的距离
    for (int i = 1; i <= G.num; i++) {
        for (int j = 1; j <= G.num; j++) {
            fw << G.arcs[i][j];
            fw << " ";
        }
        fw << endl;
    }
    fw.close();
D:  dd1();//主界面节点
    cin >> n;
    switch (n) {
    C://游客菜单节点
    case 1:dd3();//游客菜单
        cin >> n;
        switch (n) {
        case 1:user1(); goto C; break;//显示导游图
        case 2:user2(G); goto C; break;//导游图上单个景点的信息
        case 3:user3(G); goto C; break;//导游图所有景点的信息
        case 4:
            cout << "请输入两个景点的序号" << endl;
            cin >> n >> m;
            Dijkstra(G, n, m);
            goto C; break;//图中任意节点的问路查询
        case 5:goto A; break;//退回主菜单
        default:cout << "您的输入错误,请重新输入" << endl; goto A; break;
        }
        break;
    case 2:while (pass(password) == 0) {//密码错误5次回到主菜单
        i++;
        if (i % 5 == 0) {
            cout << "您已错误五次,已自动退回到主菜单" << endl;
            goto D;
        }
    };
      B:    //管理员菜单节点 
          dd5();
          cin >> n;
          switch (n) {
          case 1:cout << "请输入新密码" << endl;
              fw.open("text.txt");  //打开text.txt
              cin >> password;
              fw << password;                          //在text.txt中输出一个数
              fw.close();                     //关闭文件
              cout << "密码已修改,请重新登录" << endl;
              goto D; break;//修改密码
          case 2:add(&G); goto A; break;//新增景点
          case 3: change(&G); goto A; break;//改变景点信息
          case 4:addway(&G); goto A; break;//添加新路径
          case 5:goto D; break;//退出管理员系统
          default:cout << "你的输入错误,请重新输入" << endl; goto B; break;
          }
          break;
    case 3:break;//退出程序
    default:cout << "你的输入错误,请重新输入" << endl; goto D; break;
    }
}
void add(school* G) {//添加景点
    G->num++;
    int i = G->num;
    for (int j = 1; j <= i; j++) {
        G->arcs[i][j] = MAX;
        G->arcs[j][i] = MAX;
    }
    G->arcs[G->num][G->num] = 0;
    G->vex[i].number = G->num;
    cout << "请输入添加景点的名字:" << endl;
    cin >> G->vex[i].sight;
    cout << "请输入该景点与几个景点相连" << endl;
    int n = 0;
    cin >> n;
    for (int j = 0; j < n; j++) {
        int m = 0;
        cout << "请输入与该景点相邻景点的编号与距离" << endl;
        cin >> m;
        cin >> G->arcs[m][i];
        G->arcs[i][m] = G->arcs[m][i];
    }
    cout << "用一句话输入新建景点的大概信息" << endl;
    cin >> G->vex[i].data;
    cout << "景点添加成功" << endl;
}
bool change(school* G) {//修改景点信息
    cout << "请输入要修改景点的编号" << endl;
    int n = 0;
    cin >> n;
    if (n > G->num || n <= 0) {
        cout << "您的输入错误,地图中没有此景点,请重新输入:" << endl;
        return false;
    }
    cout << "请选择需要修改的信息 :" << endl << "1.景点的名字" << endl << "2.景点的介绍" << endl;
    int m = 0;
    cin >> m;
    switch (m) {
    case 1:cout << "请输入景点的名字" << endl;    cin >> G->vex[n].sight; break;
    case 2:cout << "请输入景点的介绍" << endl;    cin >> G->vex[n].data; break;
    default:cout << "您的输入错误" << endl;
    }
}
bool addway(school* G) {//新建景点路径
    cout << "请输入两个景点的编号" << endl;
    int m = 0, n = 0;
    cin >> m >> n;
    if (m == n || m<1 || n<1 || m>G->num || n>G->num) {
        cout << "您的输入错误" << endl;
        return false;
    }
    cout << "请输入景点之间的距离" << endl;
    cin >> G->arcs[m][n];
    G->arcs[n][m] = G->arcs[m][n];
    cout << "新增路径成功" << endl;
}
bool user2(school G) {//导游图上单个景点的信息
    cout << "请输入要查找景点的序号" << endl;
    int n = 0;
    cin >> n;
    if (n<1 || n>G.num) {
        cout << "没有此景点" << endl;
        return false;
    }
    cout << G.vex[n].sight << "    " << G.vex[n].data << endl;
}
void user3(school G) {//导游图所有景点的信息
    for (int i = 1; i <= G.num; i++) {
        cout << G.vex[i].number << "   " << G.vex[i].sight << "    " << G.vex[i].data << endl;
    }
}
void Dispath(school G, int dist[], int path[], int S[], int v, int m) {
    int  j, k;
    int apath[MAXSIZE], d;
    if (S[m] == 1 && m != v) {
        cout << "从顶点" << v << "到顶点" << m << "的路径长度为:" << dist[m] << endl;
        cout << "路径为:" << endl;
        d = 1; apath[d] = m;
        k = path[m];
        if (k == -1)
            cout << "无路径" << endl;
        else
        {
            while (k != v)
            {
                d++; apath[d] = k;
                k = path[k];
            }
            d++; apath[d] = v;
            cout << apath[d];  //输出路径起点
            for (j = d - 1; j > 0; j--)
                cout << "," << apath[j];  //输出其他顶点
            cout << endl;
        }
    }
}
void Dijkstra(school G, int v, int m) {
    int dist[MAXSIZE], path[MAXSIZE];
    int S[MAXSIZE];   //S[i]表示顶点i在S中,S[i]=0表示i在U中
    int mindis, i, j, u;
    for (i = 1; i <= G.num; i++) {
        dist[i] = G.arcs[v][i];      //距离初始化
        S[i] = 0;                    //S[]置空
        if (G.arcs[v][i] < MAX)
            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 = 1; i <= G.num; i++) {//循环直到所有顶点的最短路径都求出
        mindis = MAX;              
        for (j = 1; j <= G.num; j++)  //选取不在s中具有最小值最短路径长度的顶点u
            if (S[j] == 0 && dist[j] < mindis) {
                u = j;
                mindis = dist[j];
            }
        S[u] = 1;   //顶点u加入s中
        for (j = 1; j <= G.num; j++)//修改不在s中的顶点最短路径
            if (S[j] == 0)
                if (G.arcs[u][j] < MAX && dist[u] + G.arcs[u][j] < dist[j]) {
                    dist[j] = dist[u] + G.arcs[u][j];
                    path[j] = u;
                }
    }
    Dispath(G, dist, path, S, v, m);//输出最短路径
}

   第二步,写头文件

#pragma once
#include<iostream>
#define MAXSIZE 25
#define MAX   99999
void user1();//输出导游图
void dd1();//选择登录用户
void dd3();//游客菜单
void dd5();//管理员菜单
int pass(char a[]); //判断管理员密码是否正确

第三步,写副函数

#include"maps.h"
#include<stdio.h>
using namespace std;
void dd1() {
    cout << "*******************菜单******************" << endl;
    cout << "**************请选择登录方式***************" << endl;
    cout << "*****************1.游客登录****************" << endl;
    cout << "*****************2.管理员登录**************" << endl;
    cout << "*****************3.退出********************" << endl;
}
void dd5() {//管理员操作
    cout << "1.修改登录密码" << endl;
    cout << "2.添加新的景点" << endl;
    cout << "3.修改景点信息(编号唯一,不可修改)" << endl;
    cout << "4.新建景点路径" << endl;
    cout << "5.退回到主菜单" << endl;
    cout << "请输入要进行的操作" << endl;
}
void dd3() {//游客操作
    cout << "1.显示校园导游图" << endl;
    cout << "2.导游图中的景点详情" << endl;
    cout << "3.显示所有景点的信息" << endl;
    cout << "4.图中任意节点的问路查询" << endl;
    cout << "5.退回到主菜单" << endl;
}
void user1() {//输出导游图
    printf("\n\n\n");
    printf("\t  *******************河南财经政法大学****************");
    printf("\n\n\n");
    printf("                               ------------------------15游泳池        \n");
    printf("                               |                          |            \n");
    printf("                               |                          |            \n");
    printf("12洗浴中心----------------13骊绣苑---------------------16主田径场      \n");
    printf("       |                       |                          |            \n");
    printf("10超市----11榴馨苑          14综合楼                      |            \n");
    printf("    |          |                |----------------------17综合文体馆    \n");
    printf("9开水房        |                                            |  \n");
    printf("    |          ------------8图书馆--------------------------|  \n");
    printf("    |                          |                            |  \n");
    printf("    |-------------6实验楼------|--------7三号教学楼         |  \n");
    printf("                     |         |              |             |  \n");
    printf("                     |         |              |             |  \n");
    printf("              4一号教学楼------|--------5二号教学楼         |  \n");
    printf("                               |                            |  \n");
    printf("                               |                            |  \n");
    printf("                               |---2行政楼---------------3北区 \n");
    printf("                               |                               \n");
    printf("                               |                               \n");
    printf("                              1大门口                          \n");
}
int pass(char a[]) {//判断密码是否正确
    int i = 0;
    char b[20];
    cout << "请输入管理员密码" << endl;
    cin >> b;
    while (a[i] != '\0' || b[i] != '\0') {
        if (a[i] != b[i]) {
            cout << "密码错误,请重新输入密码" << endl;
            return 0;
        }
        i++;
    }
    cout << "密码正确" << endl;
    return 1;
}


在主函数中我们需要从txt文本中读入管理员密码

创建text.txt文件,然后在里面输入初始化密码

内容如下

12345678

创建text1.txt文件

然后在里面输入景点的初始信息

需要注意的是:每个景点与序号直间需要一个空格,防止数据读入错误,每个景点之间要换行。

内容如下

1 大门口 出入学校的必经之路
2 行政办公楼 学校最气派的建筑之一
3 北区教室实训中心 金工实训中心,还有几排具有历史沧桑感的教室
4 一号教学楼 主要有小教室,用来上英语课和专业课
5 二号教学楼 主要用来上专业课,五六楼有语音室
6 实验楼 学生上各种实验课的地点
7 三号教学楼 有大教室,一般安排用来上基础课
8 图书馆 学校为同学们提供学习和自习的地方,也是学校的藏书最多的地方
9 开水房 学校唯一一个为同学提供热水的地点
10 超市 学校唯一一个中型超市,在这里可以买到各种生活用品
11 榴馨苑 环境较好的学生食堂,这里因为离女生公寓较近,所以这个食堂女生较多
12 洗浴中心 环境还行就是规模太小,每天都是供不应求
13 骊秀苑 主要经营面食。我校的物美价廉的食堂,位于男生公寓区,大部分男生在此就餐
14 综合楼 历史较为悠久的一栋教学楼,旁边有学生第二俱乐部,学校的晚会都在这里举行
15 游泳池 大一学生上游泳课的地点
16 主田径场 标准的400m跑道,学生上室外体育课的地点
17 综合问题馆 上室内体育课的地方,是新建成的较为气派


然后创建text2.txt文件,在里面存入景点的初始个数

内容如下

17

然后创建text3.txt文件

然后在里面输入各个景点之间的路径信息,采用邻接矩阵将路径存入文档,

有路径则写入路径值,无路径则用99999表示,自身到自身的距离为0

内容如下

0 255 99999 501 535 705 722 790 99999 99999 99999 99999 99999 99999 99999 99999 99999 
255 0 314 450 484 654 663 748 99999 99999 99999 99999 99999 99999 99999 99999 99999 
99999 314 0 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 1054 
501 450 99999 0 272 178 442 527 99999 99999 99999 99999 99999 99999 99999 99999 99999 
535 484 99999 272 0 99999 187 561 99999 99999 99999 99999 99999 99999 99999 99999 99999 
705 654 99999 178 99999 0 289 374 520 99999 99999 99999 99999 99999 99999 99999 99999 
722 663 99999 442 187 289 0 382 99999 99999 99999 99999 99999 99999 99999 99999 99999 
790 748 99999 527 561 374 382 0 99999 99999 99999 99999 99999 365 99999 99999 1096 
99999 99999 99999 99999 99999 520 99999 99999 0 297 99999 99999 99999 99999 99999 99999 99999 
99999 99999 99999 99999 99999 99999 99999 99999 297 0 178 331 99999 99999 99999 99999 99999 
99999 99999 99999 99999 99999 99999 99999 99999 99999 178 0 99999 99999 99999 99999 99999 99999 
99999 99999 99999 99999 99999 99999 99999 99999 99999 331 99999 0 383 99999 99999 99999 99999 
99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 383 0 340 1003 833 99999 
99999 99999 99999 99999 99999 99999 99999 365 99999 99999 99999 99999 340 0 99999 99999 646 
99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 1003 99999 0 714 99999 
99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 833 99999 714 0 688 
99999 99999 1054 99999 99999 99999 99999 1096 99999 99999 99999 99999 99999 646 99999 688 0 


在创建的过程中要注意将,1.cpp  2.cpp masp.h添加到一个项目中,

并把所有的文件都放在一个文件夹中,否则程序可能会无法读入数据,建议用devc++来实现,

使用visual studio 可能会无法读入text文档的数据,还需要将文档设置一写属性才可以使用,

还是比较建议使用devc++

操作

 将三个源文件添加到项目中,并且将所有txt文件都放入一个文件夹中,然后将所有源文件编译

就能够运行了。

运行实录

 

 

 

 

 需要注意的是,管理员中修改景点的数据之后回直接在txt文件中保存下来,所以运行之前要

注意备份

还有链接放在下面了

链接:https://pan.xunlei.com/s/VMst-zAOqiewLRMFoOe5jXxhA1
提取码:zs9e
复制这段内容后打开手机迅雷App,查看更方便

这个程序是直接可以运行的

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

财大彭于晏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值