1.任务:

[问题描述]

上网下载真实南京公交线路图,建立南京主要公交线路图的存储结构。

[基本要求]

(1)输入任意两站点,给出转车次数最少的乘车路线。

(2)输入任意两站点,给出经过站点最少的乘车路线。

2.采用的数据结构

使用顺序结构,队列和图

3.算法设计思想

建立公交车类型结构,对于每辆车的编号,经过的站点数和经过的站点编号进行存储。建立公交站台类型结构,对于每个编号的公交站点的名称,经过该站点的公交车的数量和编号进行存储。

当寻找经过站点数最少的方案时,使用广度优先遍历,逆向存储,从终点站起,对每个在栈中的站点的公交线路进行遍历,使该线路上该站点的前后站(未进栈过的)依次进栈并标记,记录进栈站点的后一站点和公交线路,直至找到起点站。

当寻找换乘次数最少的方案时,使用深度优先遍历,逆向存储,从终点起,对每个在栈中的站点的公交线路进行遍历,使该线路上每一个未进栈的站点进栈,并标记其后一站点和公交线路,直至找到起点站为止。

4.源程序

#include <iostream>
#include <string.h>
#include <fstream>
#include <sstream>
#include <string>
#include <windows.h>
using namespace std; typedef struct Bus
{int No;                         //该公交车的编号int StationCount;               //该公交车经过的站点数量int BusRoute[80];               //该公交车依次经过的站点编号
}Bus;typedef struct Station
{char StationName[60];          //站点名称int BusCount;                  //经过该站点的公交车数量short int bus[35];             //经过该站点的公交车的编号
}Station;typedef struct BusMap
{Bus bus[1000];Station station[10000];int BusCount;                  //公交车数量int StationCount;              //站点数量
}BusMap;int GetBusStation(BusMap &M, char busname[60])            //获取站台名对应的编号
{for (int i=1;i<=M.StationCount;i++){if (strcmp(M.station[i].StationName,busname)==0){return i;}}return 0;
}int IncreaseBusStation(BusMap &M, char busname[60])
{int num=GetBusStation(M,busname);if (num==0){strcpy(M.station[++M.StationCount].StationName,busname);num=M.StationCount;}M.bus[M.BusCount].BusRoute[M.bus[M.BusCount].StationCount]=num;M.station[num].bus[++M.station[num].BusCount] = M.bus[M.BusCount].No;for (int i=0;i<60; i++){busname[i]='\0';}return num;
}int CreateMap(BusMap &M)                                  //创建图
{M.BusCount=0;M.StationCount=0;for (int i=0; i<1000;i++){M.bus[i].StationCount=1;}for (int i=0;i<10000;i++){M.station[i].BusCount=0;}int num=0;char busname[60];char ch;FILE *fp;if ((fp=fopen("南京公交线路.txt", "r"))==NULL){printf("文件打开失败\n");exit(0);}fscanf(fp, "%d", &M.bus[++M.BusCount].No);while (ch!=' '){ch=fgetc(fp);}while (1){ch=fgetc(fp);if (feof(fp)){IncreaseBusStation(M,busname);break;}if(ch==' '){continue;}if(ch==','){IncreaseBusStation(M,busname);num=0;M.bus[M.BusCount].StationCount++;continue;}if(ch=='\n'){IncreaseBusStation(M,busname);num=0;char chh;chh=fgetc(fp);if (feof(fp)){break;}fseek(fp, -1L, 1);fscanf(fp, "%d", &M.bus[++M.BusCount].No);while (ch != ' '){ch = fgetc(fp);}continue;}busname[num++]=ch;}fclose(fp);
}int GetBus(BusMap &M, int No)                             //获取公交线路对应的编号
{for (int i=1; i<= M.BusCount;i++){if (M.bus[i].No == No){return i;} }return 0;
}typedef struct LNode                                      //队列基本操作
{int data;struct LNode *next;
}LNode,*QueuePtr;typedef struct LinkQueue
{QueuePtr front;QueuePtr rear;
}LinkQueue;void InitQueue(LinkQueue &Q)
{Q.front=Q.rear=(LNode *)malloc(sizeof(LNode));if(Q.front==NULL) exit -1;Q.front->next=NULL;
}int QueueEmpty(LinkQueue Q)
{if (Q.front!=Q.rear){return 0;}else{return 1;}
}void EnQueue(LinkQueue &Q,int e)
{LNode *s;s=(LNode *) malloc(sizeof(LNode));if(s==NULL) exit -1;s->data=e;Q.rear->next=s;Q.rear=s;
}int DeQueue(LinkQueue &Q)
{LNode *p;int e;if (Q.front==Q.rear) return -1;p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear == p){Q.rear=Q.front;}free(p);return e;
}typedef struct info                           //PreStation记录前一站号,busno记录经过该站所乘坐的公交车
{int NextStation;int busno;short int visited;
}info;info k[10000];int FindLeastStationNum(BusMap &M,char StartStation[60],char EndStation[60])         //寻找乘坐站数最少的方案
{int start,end;start=GetBusStation(M,StartStation);end=GetBusStation(M,EndStation);for(int i=1;i<10000;i++){k[i].visited=0;k[i].NextStation=i;k[i].busno=0;}LinkQueue Q;InitQueue(Q);EnQueue(Q,end);                          //倒序查找 k[end].visited=1;int count=1;while(1){count++; EnQueue(Q,-1);                        //-1为标记 while(Q.front!=Q.rear){end=DeQueue(Q);if(end==-1){break;}for(int i=1;i<=M.station[end].BusCount;i++)                     //遍历所有经过此站的线路 {int b;b=GetBus(M,M.station[end].bus[i]);for(int j=1;j<=M.bus[b].StationCount;j++){if (M.bus[b].BusRoute[j]==end)                         //找到该路车中该站点的序号 {if (M.bus[b].BusRoute[j+1]==start || M.bus[b].BusRoute[j-1]==start)    //下一站或上一站为起始站 {int bus=k[end].busno;printf("最少经过%d个站点\n\n",count);cout<<M.station[start].StationName;printf("(乘坐%d路)->", M.bus[b].No);count--;while(count--){if (count==0){cout<<M.station[end].StationName<<"(到达终点,下车)"<<endl; }else{cout<<M.station[end].StationName;printf("(乘坐%d路)->" ,bus);}end=k[end].NextStation;bus=k[end].busno;}return 1;}if ((k[M.bus[b].BusRoute[j-1]].visited==0) && (j-1>0) )                       //当前一站存在且未被访问 {k[M.bus[b].BusRoute[j-1]].busno = M.bus[b].No;k[M.bus[b].BusRoute[j-1]].NextStation=end;EnQueue(Q, M.bus[b].BusRoute[j-1]);k[M.bus[b].BusRoute[j-1]].visited=1;}if ((k[M.bus[b].BusRoute[j+1]].visited==0) && (j+1<=M.bus[b].StationCount))    //当后一站存在且未被访问 {k[M.bus[b].BusRoute[j+1]].busno=M.bus[b].No;k[M.bus[b].BusRoute[j+1]].NextStation=end;EnQueue(Q, M.bus[b].BusRoute[j+1]);k[M.bus[b].BusRoute[j+1]].visited=1;}break;}}}}}
}int FindLeastTransfer(BusMap &M,char StartStation[60],char EndStation[60])         //寻找转车最少的方案
{int start,end;start=GetBusStation(M,StartStation);end=GetBusStation(M,EndStation);for(int i=1;i<10000;i++){k[i].visited=0;k[i].NextStation=i;k[i].busno=0;}LinkQueue Q;InitQueue(Q);EnQueue(Q,end);                          //倒序查找 k[end].visited=1;int count=1;while(1){EnQueue(Q,-1);while(Q.front!=Q.rear){end=DeQueue(Q);if(end==-1){count++;break;}for(int i=1;i<=M.station[end].BusCount;i++){int b;b=GetBus(M,M.station[end].bus[i]);for(int j=1;j<=M.bus[b].StationCount;j++){if(M.bus[b].BusRoute[j]==start){int bus;bus=k[end].busno;printf("至少需要乘坐%d班公交车\n",count);cout<<M.station[start].StationName;printf("(乘坐%d路公交车)->",M.bus[b].No);while(count--){if(count==0){cout<<M.station[end].StationName<<"(到达终点,请下车!)"<<endl;}else{cout<<M.station[end].StationName;printf("(换乘%d路车)->",bus);}end=k[end].NextStation;bus=k[end].busno;}return 1;}else if(k[M.bus[b].BusRoute[j]].visited==0){k[M.bus[b].BusRoute[j]].visited=1;k[M.bus[b].BusRoute[j]].busno=M.bus[b].No;k[M.bus[b].BusRoute[j]].NextStation=end;EnQueue(Q,M.bus[b].BusRoute[j]);}}}}}
}int FindLeastTransfer1(BusMap &M,char StartStation[60],char EndStation[60])         //寻找转车最少的方案(具体)
{int start,end;start=GetBusStation(M,StartStation);end=GetBusStation(M,EndStation);int end1=end;for(int i=1;i<10000;i++){k[i].visited=0;k[i].NextStation=i;k[i].busno=0;}LinkQueue Q;InitQueue(Q);EnQueue(Q,end);                          //倒序查找 k[end].visited=1;while(1){EnQueue(Q,-1);while(Q.front!=Q.rear){end=DeQueue(Q);if(end==-1){break;}for(int i=1;i<=M.station[end].BusCount;i++){int b;b=GetBus(M,M.station[end].bus[i]);int loc; for(int j=1;j<=M.bus[b].StationCount;j++){if(M.bus[b].BusRoute[j]==end){loc=j;break;}}for(int j=loc+1;j<=M.bus[b].StationCount;j++){if(M.bus[b].BusRoute[j]==start){int bus;bus=k[end].busno;printf("具体公交路线如下:\n");cout<<M.station[start].StationName;printf("(乘坐%d路公交车)->",M.bus[b].No);while(end!=end1){cout<<M.station[end].StationName;printf("(乘坐%d路车)->",bus);end=k[end].NextStation;bus=k[end].busno;}cout<<M.station[end].StationName<<"(到达终点,请下车!)"<<endl;return 1;}else if(k[M.bus[b].BusRoute[j]].visited==0){k[M.bus[b].BusRoute[j]].visited=1;k[M.bus[b].BusRoute[j]].busno=M.bus[b].No;k[M.bus[b].BusRoute[j]].NextStation=M.bus[b].BusRoute[j-1];EnQueue(Q,M.bus[b].BusRoute[j]);}}for(int j=loc-1;j>=1;j--){if(M.bus[b].BusRoute[j]==start){int bus;bus=k[end].busno;printf("具体公交路线如下:\n");cout<<M.station[start].StationName;printf("(乘坐%d路公交车)->",M.bus[b].No);while(end!=end1){cout<<M.station[end].StationName;printf("(乘坐%d路车)->",bus);end=k[end].NextStation;bus=k[end].busno;}cout<<M.station[end].StationName<<"(到达终点,请下车!)"<<endl;return 1;}else if(k[M.bus[b].BusRoute[j]].visited==0){k[M.bus[b].BusRoute[j]].visited=1;k[M.bus[b].BusRoute[j]].busno=M.bus[b].No;k[M.bus[b].BusRoute[j]].NextStation=M.bus[b].BusRoute[j+1];EnQueue(Q,M.bus[b].BusRoute[j]);}}}}}
}int main()
{BusMap M;CreateMap(M);char start[60],end[60];printf("请输入起点:");cin>>start;fflush(stdin);printf("请输入终点:");cin>>end;printf("----------------------------------\n\n");if(GetBusStation(M,start)==0 || GetBusStation(M,end)==0){printf("站点输入有误!\n");}else{FindLeastStationNum(M,start,end);printf("\n----------------------------------\n\n");FindLeastTransfer(M,start,end);printf("\n");FindLeastTransfer1(M,start,end);}return 0;
}

5.源程序测试数据及结果

 公交线路提示测试数据及结果

6.存在问题及解决办法

在存储车站和公交路线时,使用了数组,无法把握空间,可能会产生大空间的浪费或是溢出的问题。但是由于各个站点经过的公交车数不同,无法使用链表进行存储。可以考虑在之后采用动态存储,例如vector等,不易产生空间问题。

7.文档内容

  

txt文档中每一行表示一个线路,线路号(注意不一定连续,可能有部分数字线路不存在)和后面站名之间用空格分隔,各站名之间用英语逗号分隔。

(好像没有找到上传文档链接的方法,有需要可以私发邮箱)

数据结构课程设计4:公交线路提示相关推荐

  1. 公交换乘系统c语言,数据结构课程设计报告(公交换乘).docx

    课 程 设 计 报 告 题目: 武昌地区公交查询与换乘推荐 课程名称: 数据结构课程设计 专业班级: 学 号: 姓 名: 指导教师: 报告日期: 计算机科学与技术学院 任 务 书 设计内容 掌握图.查 ...

  2. 课程设计:公交线路管理系统

    #include <iostream> #include <string> #include<iomanip> #include <fstream> u ...

  3. 算法与数据结构课程设计城市公交管理系统(C、C++)

    城市公交管理系统 项目功能模块(需要源码请私信) 1.添加功能: [1]添加公交站,将站点信息写入stations.txt中: [2]添加交通路线,将路线信息写入bus.txt中: 2.删除功能: [ ...

  4. 数据结构课程设计 公交系统

    大家好! 这是我的第一篇文章,是将这学期的数据结构课设报告整理出来的.可能还有些小错误,还请多多指正. 数据结构课程设计<公交系统> 一.引言 (一)课题描述 (二)设计要求 二.总体设计 ...

  5. 基于数据结构和C语言实现公交管理系统(含文档和代码)数据结构课程设计

    目录 第1章 课程设计内容及要求 第2章 需求分析 第3章 算法设计 3.1 设计思想 3.2 设计表示 第4章 系统调试及测试(含代码) 4.1 功能截图 4.2 实现代码 第5章 课程设计心得 5 ...

  6. C/C++数据结构课程设计安排

    C/C++数据结构课程设计安排 数据结构课程设计安排 课程设计学时:32学时 课程设计目的:综合应用数据结构课程中所学的数据结构:线性表.栈.队列.数组.广义表.树.二叉树.图.查找表中的一种或多种数 ...

  7. 山东大学数据结构课程设计实验五(低风险出行系统)

    数据结构课程设计(五)--低风险出行系统 前言 题目要点 ①生成数据 ②要给定两种最短路解法 ③创立文件 ④模拟时间流动并与用户交互 代码讲解 源代码 写在最后 前言 数据结构课程设计第五题是每一个同 ...

  8. 设树采用孩子兄弟表示法存放.用类c语言设计算法计算树的高度.,(数据结构课程设计分类题目.doc...

    (数据结构课程设计分类题目 线性表 顺序表: 1.设有一元素为整数的线性表L=(a1,a2,a3,-,an),存放在一维数组A[N]中,设计一个算法,以表中an作为参考元素,将该表分为左.右两部分,其 ...

  9. c语言数据结构课程设计停车场管理系统,数据结构课程设计报告停车场管理系统...

    <数据结构课程设计报告停车场管理系统>由会员分享,可在线阅读,更多相关<数据结构课程设计报告停车场管理系统(8页珍藏版)>请在人人文库网上搜索. 1.数据结构课程设计报告系 别 ...

最新文章

  1. iOS7系统iLEX RAT冬青鼠安装教程:无需刷机还原纯净越狱系统
  2. [云炬创业管理笔记]第一章测试5
  3. 马氏距离详解(数学原理、适用场景、应用示例代码)
  4. 案例分析:倾斜值传入导致 SQL 资源消耗升高
  5. Spring Data Jpa的@Temporal注解
  6. 分布式文件系统HDFS 学习指南
  7. selenium弹窗无法定位_Selenium异常集锦
  8. 48.怎样消除桌面图标上的小箭头:
  9. sysbench压测cpu,io,memory,threads,mutex
  10. 学习windows内核一
  11. 如何实现 ASP.NET Core WebApi 的版本化
  12. 投标书如何写?(转)
  13. 强大的安全工具 杀毒软件小红伞试用测评
  14. Android String字符串截取方法总结
  15. Panda3D学习 (1):小行星示例程序
  16. mac安装homebrew + git + nodejs
  17. java大写英文字母_输出一个字符串中的大写英文字母数,小写英文字母数以及非英文字母(.java)...
  18. Google Play游戏服务入门
  19. 联想xt92耳机测评
  20. v2视频服务器退出系统怎么启动,v2会议视频系统

热门文章

  1. Git如何将代码回退到一个历史的版本
  2. apache shardingsphere 【实现oracle数据库按月分片】
  3. 高级程序员如何面对职场压力?(3)--明确目标赢在职场
  4. 前端基础入门——让页面动起来的JS基础部分
  5. vscode中使用git合并分支
  6. 深入了解IMGUI和编辑器自定义
  7. modprobe和insmod之间的区别,rmmod和lsmod介绍
  8. 零基础搭建微服务框架/Spring Boot + Dubbo + Docker + Jenkins
  9. LKT(LCS)安全芯片RSA密钥存储格式说明
  10. 神奇的AI:将静态图片转为3D动图