数据结构课设城市公交查询系统(C语言)

公交线路图


一. 设计要求:

1、需要用到多个文件,例如文本文件,文件名stations.txt,保存站点信息,格式可以自行设计,例如:编号 站名。等等

2、设计公交线路所需的存储结构,将文件中的数据读入内存。

3、提供用户操作的菜单和界面实现添加、删除、修改公交、站点、线路信息,注意数据间的关联性。

4、将修改后的信息保存回文件。

5、其他查询操作参见教程。


二. 设计内容:

1、 数据格式**:**

在这个课设中我设计的是两个文件,一个文件用来存放公交车站名的“stations.txt”,一个用来存放公交线路“bus.txt”。

(1)**“stations.txt”**文件的第一行,记录的为公交车站的数量,依次往下,为所存的公交车站名,其格式为:

① 公交车站数

② 公交车站名

③ 公交车站名

④ 公交车站名
在这里插入图片描述

(2)**“bus.txt****”**文件的第一行,记录的为公交车每个站之间有几条线路,就是一站算一条线路(例如:公交车从仙来广场到庆丰苑是走了一条线路,从仙来广场到金三角,就要先从仙来广场到庆丰苑,再从庆丰苑到金三角,这样看,是走了两条线路) 第二行开始记录公交名,公交车的一条线路的起点和终点,还有两站之间的距离,其格式为:

① 公交线路数量

② 公交车名 起始站 终点站 距离

③ 公交车名 起始站 终点站 距离

④ 公交车名 起始站 终点站 距离

…………………………
例如:
公交车名 起始站 终点站 距离
105 图书馆 人民政府 432
105 人民政府 万达广场 856
这就说明105路公交车,会经过图书馆–>人民广场–>万达广场。


2、 数据结构**:**

将文件中的数据读入内存,建立图的存储结构,,以下为存储结构的C语言定义:

typedef int StationsType;//StationsType 定义整形的变量

typedef struct TrafficNode

{

char name[MAX_STRING_NUM]; //公交号

int EndCity; //该有向边指向的顶点在数组中的位置,即该公交站编号

int Number ; //用于记录每站之间的距离

} TrafficNodeDat;

typedef struct VNode

{

StationsType stations;

int BusNum; // 标记下面 Bus 数组里元素个数

TrafficNodeDat Bus[MAX_TRAFFIC_NUM]; // 数组成员为结构体,记录了到达的终点站、距离、和公交号

} VNodeDat;

VNodeDat AdjList[MAX_VERTEX_NUM];


3、 查询公交线路:

当输入公交号后,就会输出公交线路的信息如下图:
在这里插入图片描述

4、 添加公交站:

输入公交站名存储成功后会输出Save OK
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKpqZTno-1590671092779)(file:///C:/USERS~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg)]

5、 删除公交站:

输入公交需要删除的公交站成功会提醒:
在这里插入图片描述

6、 添加公交线路:

输入所规定的起始,终点站,公交号和两站之间的距离:
在这里插入图片描述

7、 删除公交:

输入公交号删除成功则输出OK:
在这里插入图片描述


二. 系统子程序及功能设计**:**

int ShowMenu()

int SeekStations(char *name) // 寻找公交站

int SearchBus(char *name)// 查询公交站

int InsertStations(char *Name) // 添加公交站

int DelStations(char *Name) // 删除公交站

int SaveSysInfo() // 向程序输入数据

int InsertBus(char *bus, char *StartCity, char *EndStations, int number)//添加公交

int DelPath(char *name)// 删除公交

int InitSysData();


三.实验总结:

1. 在做课设的时候,起初我设计的是一个公交一次性输入许多路线,这样也十分的符合公交的特性,但是在做到最优路径的是吧,出现了大量的bug,于是我进行了查阅资料,于是我就改成了现在的这样,两站两站的输入信息和存储信息,只要起始站和终点站,这样设计。虽然这样麻烦许多,但是在设计的时候自己对于这种方法掌握的更快一点,于是终于设计出来了这个课设。

2. 这个课设还是有很大的完善空间,在继续最优路径搜索的时候,在某些情况下会出现无法输出的情况,在进行了测试后,发现对于一些不存在的公交站查询的时候,不会报错,同时在输出的时候,不是很人性化,同时该程序的一些地方写的代码十分的繁琐,从而影响了运行速度。这些都是在之后的学习中,需要改进和完善的地方。


四.程序代码**

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ERR 0
#define OK 1
#define Dij_MAXN 100
#define MAX_VERTEX_NUM 100
#define MAX_STRING_NUM 100
#define MAX_TRAFFIC_NUM 100

const char StationsFile[] = "stations.txt";
const char BusFile[] = "bus.txt";
typedef int StationsType;//StationsType  定义整形的变量
typedef struct TrafficNode
{
    char name[MAX_STRING_NUM]; // 公交号  //MAX_STRING_NUM 最为 10
    int EndStations; // 该有向边指向的顶点在数组中的位置,即该公交站编号
    int Number ; // 用于记录每站之间的距离
} TrafficNodeDat;
typedef struct VNode
{
    StationsType stations;
    int BusNum; // 标记下面 Bus 数组里元素个数
    TrafficNodeDat Bus[MAX_TRAFFIC_NUM]; // 数组成员为结构体,记录了到达的终点站、距离0、和公交号
} VNodeDat;

VNodeDat AdjList[MAX_VERTEX_NUM];
char StationsName[MAX_VERTEX_NUM][MAX_STRING_NUM]; // 公交站名,采用第一下标为该城市在本程序中的编号
int StationsNum; // 公交站数目


int ShowMenu()
{
    printf("\n|****************** 欢迎使用城市交通系统 *******|\n");
    printf("\n|------------------1:  添加公交站 --------------|");
    printf("\n|------------------2:  删除公交线路 ------------|");
    printf("\n|------------------3:  添加交通路线 ------------|");
    printf("\n|------------------4:  删除公交 ----------------|");
    printf("\n|------------------5:  查询最短的路线 ----------|");
    printf("\n|------------------6:  查询公交线路 ------------|");
    printf("\n|------------------7:  清除屏幕 ----------------|");
    printf("\n|------------------0:  退出 --------------------|");
    printf("\n|***********************************************|\n");
    printf("\n 请输入你的选择 :");
    return 0;
}

int SeekStations(char *name) // 寻找公交站
{
    int i;
    for (i = 0; i<StationsNum; i++)
    {
        if (strcmp(name, StationsName[i]) == 0) // 比较函数,若相等,则返回 i 值
        {
            return i;
        }
    }
    return -1;
}


int SaveSysInfo() // 向程序输入数据
{
    FILE *fp;
    int i, j, total;
    fp = fopen(StationsFile, "w"); // 打开 StationsFile 文档
    fprintf(fp, "%d\n", StationsNum); // 往文档中写公交站的数量
    for (i = 0; i<StationsNum; i++)
    {
        fprintf(fp, "%s\n", StationsName[i]); // 往文档中写公交站的名字
    }
    fclose(fp);// 将 StationsFile 文档关闭
    total = 0;
    fp = fopen(BusFile, "w");// 打开 BusFile 文档
    for (i = 0; i<StationsNum; i++) // 计算公交的数量
    {
        total += AdjList[i].BusNum;
    }
    fprintf(fp, "%d\n", total); // 往文档中写公交的数量
    for (i = 0; i<StationsNum; i++) //
    {
        for (j = 0; j<AdjList[i].BusNum; j++) // 往文档中写公交的车次、始发站、终点站
        {
            fprintf(fp, "%s %s %s ", AdjList[i].Bus[j].name,
                                     StationsName[i],
                                     StationsName[AdjList[i].Bus[j].EndStations]);
            fprintf(fp, " %d\n", AdjList[i].Bus[j].Number);// 往文档中写
        }
    }
    fclose(fp);

    return 1;
}

int InsertStations(char *Name) // 添加公交站
{
    strcpy(StationsName[StationsNum], Name);
    AdjList[StationsNum].stations = StationsNum;
    AdjList[StationsNum].BusNum = 0;
    StationsNum++;
    return 1;
}

int DelStations(char *Name) // 删除公交站
{
    int stations, i, j,o=1,k=0;
    stations = SeekStations(Name);
    printf("%s",Name);
    while (true)
    {
        while (strcmp(StationsName[k], Name) != 0)
        {
            k++;
        }
        if (k > StationsNum)
        {
            o--;
            printf(" 未找到此公交站,请重新输入! ");
            return 0;
        }
        for (i = stations; i < StationsNum - 1; i++)
        {
            strcpy(StationsName[i], StationsName[i + 1]);
            AdjList[i].BusNum = AdjList[i + 1].BusNum;
            for (j = 0; j < AdjList[i].BusNum; j++)
            {
                strcpy(AdjList[i].Bus[j].name, AdjList[i + 1].Bus[j].name);
                AdjList[i].Bus[j].EndStations = AdjList[i + 1].Bus[j].EndStations;
                AdjList[i].Bus[j].Number = AdjList[i + 1].Bus[j].Number;
            }
        }
        StationsNum--;
    }
    return 1;
}

int InsertBus(char *bus, char *StartCity, char *EndStations, int number)//添加公交
{
    int i, j;
    i = SeekStations(StartCity);
    j = SeekStations(EndStations);
    AdjList[i].Bus[AdjList[i].BusNum].Number = number;
    AdjList[i].Bus[AdjList[i].BusNum].EndStations = j;
    strcpy(AdjList[i].Bus[AdjList[i].BusNum].name, bus);
    AdjList[i].BusNum++; // 公交的数加 1
    return 1;
}

int DelPath(char *name)// 删除公交
{
    int i, j, flag = 0;
    for (i = 0; i<StationsNum; i++)
    {
        for (j = 0; j<AdjList[i].BusNum; j++)
            if (strcmp(AdjList[i].Bus[j].name, name) == 0)
            {
                flag = 1;
                break;
            }
        if (flag==0)
        {
            for (; j<AdjList[i].BusNum - 1; j++) // 把删除的公交后的每个公交都前移一位
            {
                AdjList[i].Bus[j].Number = AdjList[i].Bus[j + 1].Number;
                AdjList[i].Bus[j].EndStations = AdjList[i].Bus[j + 1].EndStations;
                strcpy(AdjList[i].Bus[j].name, AdjList[i].Bus[j + 1].name);
            }
            AdjList[i].BusNum--;
            break;
        }
    }
    return 1;
}

int InitSysData()
{
    FILE *fp;
    int i, j, num, number;
    char stmp1[MAX_STRING_NUM];
    char stmp2[MAX_STRING_NUM];
    char stmp3[MAX_STRING_NUM];
    fp = fopen(StationsFile, "r");
    if (!fp)
    {
        printf("\nError:Cannot Open Stations File...\n");
        return -1;
    }
    fscanf(fp, "%d", &StationsNum);
    for (i = 0; i<StationsNum; i++)
    {
        fscanf(fp, "%s", &StationsName[i]);
        AdjList[i].stations = i;
        AdjList[i].BusNum = 0;
    }
    fclose(fp);
    fp = fopen(BusFile, "r");
    if (!fp)
    {
        printf("\nError:Cannot Open Bus File...\n");
        return -1;
    }
    fscanf(fp, "%d", &num);
    for (i = 0; i<num; i++)
    {
        fscanf(fp, "%s", &stmp1); // 公交的车次
        fscanf(fp, "%s", &stmp2); // 公交的始发站
        fscanf(fp, "%s", &stmp3); // 公交的终点站
        j = SeekStations(stmp2);
        AdjList[j].Bus[AdjList[j].BusNum].EndStations = SeekStations(stmp3); // 将公交的车号、始发站、终点站读出
        strcpy(AdjList[j].Bus[AdjList[j].BusNum].name, stmp1);
        fscanf(fp, "%d", &number);
        AdjList[j].Bus[AdjList[j].BusNum].Number = number;
        AdjList[j].BusNum++;
    }
    fclose(fp);
    return 1;
}

int SearchBus(char *name)// 查询公交站
{
    FILE *fp;
    int i, j, num, number;
    char stmp1[MAX_STRING_NUM];
    char stmp2[MAX_STRING_NUM];
    char stmp3[MAX_STRING_NUM];
    int stmp4;
    fp = fopen(BusFile, "r");
    if (!fp)
    {
        printf("\nError:Cannot Open Bus File...\n");
        return -1;
    }
    fscanf(fp, "%d", &num);
    for (i = 0; i<num; i++)
    {
        fscanf(fp, "%s", &stmp1); // 公交的车次
        fscanf(fp, "%s", &stmp2); // 公交的始发站
        fscanf(fp, "%s", &stmp3); // 公交的终点站
        fscanf(fp, "%d", &stmp4); // 公交站之间的距离
        if(strcmp(stmp1,name) == 0)
        {
            printf("%s  %s  %s  %d\n" , stmp1 ,stmp2 ,stmp3 ,stmp4);
        }
    }
    fclose(fp);
    return 1;
}

int main()
{
    char name[MAX_STRING_NUM]; // 公交站名
    char s_city[MAX_STRING_NUM]; // 始发站
    char e_city[MAX_STRING_NUM]; // 终点站
    int Command, number = 1;
    int startcity, endcity, traveltype = 0;
    while (true)
    {
        printf("\n");
        ShowMenu(); // 主菜单
        scanf("%d", &Command);// 输入选择
        switch (Command) // 对菜单的内容进行选择
        {
        case 0: // 退出
            return 0;
        case 1: // 添加公交
            InitSysData(); // 读出文档中已存的信息
            printf("\n 输入公交站名 :");
            scanf("%s", &name); // 输入城市名
            InsertStations(name); // 将城市插入到数组中
            SaveSysInfo(); // 把公交的信息写入文档中
            printf(" Save OK!\n");
            break;
        case 2: // 删除公交站
            InitSysData(); // 读出文档中已有的信息
            printf("\n 输入公交站名 :");
            scanf("%s", &name);
            DelStations(name); // 将公交删除
            SaveSysInfo(); // 将处理过的信息写入文档中
            printf("Save OK!\n");
            break;
        case 3: // 添加路线
            InitSysData();
            printf(" 起始公交站名 :");
            scanf("%s", &s_city); // 起始站
            printf(" 终点公交站名 :");
            scanf("%s", &e_city); // 终点站
            printf(" 输入公交号  :");
            scanf("%s", &name);
            printf(" 距离 :");
            scanf("%d", &number);
            InsertBus(name, s_city, e_city, number);
            SaveSysInfo();

            printf(" Save OK!\n");
            break;
        case 4: // 删除公交
            InitSysData();
            printf(" 输入需要删除的公交车名 :");
            scanf("%s", &name);
            DelPath(name); // 将路线进行删除
            SaveSysInfo();
            printf("Save OK!\n");
            break;
        /*case 5: // 最小所坐站
            InitSysData();
            printf("\n 起始公交站 :");
            scanf("%s", &name);
            startcity = SeekStations(name);
            if (startcity<0)
            {
                printf("Error station Name:No such station!\n");
                break;
            }
            printf(" 终点公交站 :");
            scanf("%s", &name);
            endcity = SeekStations(name);
            if (endcity<0)
            {
                printf("Error station Name:No such station!\n");
                break;
            }
            //CalcMinNum(startcity, endcity, traveltype); // 计算最少的站数
            printf("\n");
            break;
            */
        case 6:
            InitSysData();
            printf(" 输入公交号 :");
            scanf("%s", &name);
            SearchBus(name);
            break;
        case 7:
            system("cls");// 清除屏幕
        }
    }
}


最后:
在本课设中对于车站的输入大家要格外注意,因为个人水平的原因,使用这种方法更让我好理解和进行搜索,在之后的学习中,我会完善该课设,在之后的博客中会进行补充。
如需要完整代码可以点击下面的链接:
数据结构课设城市公交完整代码(c语言)

  • 68
    点赞
  • 372
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
出行是人类生活的基本活动之一。城市的快速发展、科技的发展以及环保意识的增强,对城市公共交通的发展趋势的快速性、舒适性、便捷性、环保等方面提出更高要求。先进的信息技术也促进了公共交通技术的发展,从而为乘客提供了良好的出行条件,并且能够逐渐满足市民出行多样化的交通需求。为城市的进-步发展提供便捷条件,对于城市公共交通来说,必然要优先发展公交,因此,公共交通的地位也不断得到提升。 2005年以来,中国先后印发了关于优先发展城市公共交通的意见等系列文件正式确立了公交优先发展的战略思想,为优先发展城市公共交通指明了方向,有力推动了中国城市公交事业的发展。截止2009年底到全国公共汽电车运营线路网总长度28.9万公里公交专用车道里程达7452公里,10余个城市开通运营快速公交路线,公交运输总量达到780亿人次。随着时代发展,需要更便捷的生活,因此乘客需要实时的查询公交系统的信息以便出行,在此背景下,本文最主要采用vs2010来实现公交查询系统的设计采用SQLServer2008数据库来实现系统所需的数据需求。 在公交查询系统设计过程中考虑用户查询的模块为:线路查询、点查询、换乘查询,管理员模块则应该包括对数据增、删、查、改等操作,对于数据库设计应该体现出数据之间明确的联系关系。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值