C/C++城市交通网查询系统[2024-02-29]

C/C++城市交通网查询系统[2024-02-29]

3 城市交通网查询系统的设计与实现
3.1 问题概述
当今社会,随着生活水平的不断提高,人们对生活质量也越来越重视了。随着交通越来越便利,现在人们特别热衷于出门旅游。出门旅游不仅能欣赏到美丽的风景,还能释放一下工作和生活上的压力。了解当地的人文景观,风俗习惯。增长自己的见识,开阔眼界。旅游者出游线路研究与规划具有较强的理论和实践应用价值。
城市交通网查询系统的建立,就是为了为旅游者提供合理的旅游线路规划,可以减少游客旅行能源的消耗和旅行成本,节省旅行时间,提高旅行质量,从而提升游客的游览体验。合理的旅行线路规划对于提升游客的体验度具有重要意义。
3.2 任务要求
设计并实现一个城市交通网系统,系统功能包含:
(1) 新增加城市;
(2) 修改城市信息;
(3) 删除城市;
(4) 编辑城市间的关系;
(5) 显示全部城市信息;
(6) 能让用户查询任意一个城市到另一个城市之间的最短路径问题。要求:能够输出所走的路线和所走路径(或所需花费或所需时间等)。

城市交通网查询系统的设计与实现
设计并实现一个城市交通网系统,能让用户查询任意一个城市到另一个城市之间的最短路径问题。要求:能够输出所走的路线和所走路径(或所需花费或所需时间等)。
要求用文件的方式保存城市交通网信息,验收时,文件中至少包含15个以上的城市。

源码联系UP主 -> https://space.bilibili.com/329101171

3.3 实现说明
3.3.1 存储结构
城市交通网查询系统中,以城市表示数据、城市间的里程以及各种开销作为权值,形成了一个有向网。
假定顶点类型为VexTex,定义如下:

typedef struct
{
	char cityNo[10];       //城市编号
	char cityNname[20];    //城市名称
   。。。  //其它相关信息
} Vextex;

作为有向网的存储结构,常用的右两种:
(1) 邻接矩阵:用顶点数组保存各顶点(城市)的信息,邻接矩阵保存各顶点(城市)关系,适合边稠密的图,类型定义如下:

#define MAX   100             //图中最大顶点个数
typedef struct 
{  
    int vexnum, arcnum;       //顶点数,边数
    Vertex vexs[MAX];         //顶点数组
    int edges[MAX][MAX];      //边的邻接矩阵
} MGraph; 

(2) 邻接表:一种顺序结构和链式结构的组合,其中顶点表结点数组保存各顶点(城市)的信息,边表结点保存各顶点(城市)关系,适合边稀疏的图。邻接表类型定义如下:

#define MAX 100                 /*最大顶点数*/
typedef char VertexType;
typedef struct node            /*定义边表结点*/
{
   int adjvex;                  /*邻接点域*/
   struct node *next;          /*指向下一邻接点的指针域*/
}EdgeNode; 
typedef struct vexnode         /*定义顶点表结点*/
{
   VertexType data;            /*顶点域*/
   EdgeNode *firstedge;        /*指向第一条边结点*/
}VHeadNode;     
typedef struct
{
   VHeadNode adjlist[MAX];     /*邻接表头结点数组*/
   int vexnum,arcnum;              /*顶点数,边数*/
}AdjList;                      /*图的邻接表类型*/ 

3.3.2 最短路径算法
城市交通网系统中,最关键的功能是查询城市间的最短路径,常用的最短路径算法有:
(1)求单源最短路径的方法,即迪杰斯特拉(Dijkstra)路径长度递增法。
以邻接矩阵作为存储结构,迪杰斯特拉算法代码:

void ShortPath1(MGraph G,int v0,PathMatrix &P,ShorPath &D)
{
  for(i=0;i<G.vexnum;i++) { //初始化,源点序号为v0
     final[i]=false;
	P[i]=0;      //前驱顶点序号
	D[i]=G.arcs[v0][i];
    }
  D[v0]=0; final[v0]=true;
  for(i=1;i<G.vexnum;i++)  { //处理剩下的n-1个顶点
    k=minmum(D); //查找满足final[k]为false且D[k]具有最小的下标k
    final[k]=true;  //确定顶点序号k的最短路径
    for(j=0;j<G.vexnum;j++)
      if (!final[j] && D[j]>D[k]+G.arcs[k][j])  {
         D[j]=D[k]+G.arcs[k][j];  //修改路径长度
         P[j]=k;                          //修改前驱顶点编号
         }
     }
}

(2)求所有两顶点的最短路径Floyd方法,该算法通过矩阵变换进行求解,通常以邻接矩阵作为存储结构,算法代码:

void ShortPath2(MGraph G, PathMatrix &P[],ShorPath &D) 
{
 for(i=0;i<G.vexnum;i++)      
    for(j=0;j<G.vexnum;j++){       //初始化
	P[i][j]=-1;          //-1表示无中间顶点
	D[i][j]=G.arcs[i][j];}
 for(k=0;k<G.vexnum;k++)          //依次选定中间顶点V0,V1,…Vn-1
   for(i=0; i<G.vexnum;i++)       //i,j配合处理所有顶点Vi,Vj
     for(j=0; j<G.vexnum;j++)
       if (D[i][j]>D[i][k]+D[k][j]) {
           D[i][j]=D[i][k]+D[k][j]; //取较短路径
           P[i][j]=k;               //Vi到Vj的中间顶点Vk
         }
}

3.3.3 文件读写
城市交通网系统中,文件读写是必备的功能,不同的存储结构采用不同的读写方法:
(1) 邻接表:处理方式可以很简单,启动系统读入数据,退出系统时,将图数据写入文件。

int main()
{
MGraph G; 
FILE *fp;  //文件指
 	fp=fopen("GraphFile.dat","rb");  //假定文件名为GraphFile.dat
 	if (fp==NULL)
			G.vexnum= G.arcnum;  //无图文件时,进行初始化
else   fread(&G,sizeof(MGraph),1,fp);//读入图文件数据
fclose(fp);
 
 /*************************
	显示系统菜单,完成各种操作
 ***************************/
//每次退出系统时,选择是否保存图G,如果需要
//将图G写到文件GraphFile.dat中
fp=fopen("GraphFile.dat","wb");
   	fwrite(&G,sizeof(MGraph),1,fp);
fclose(fp);
}

(2) 邻接表的读写方法:

int SaveGraph(ALGraph G, char FileName[])
{   //将图的数据写入到文件FileName中
    int i=0;
    ArcNode *p=NULL;
    FILE *fp=fopen(FileName,"w");
    while(i<G.vexnum){
 fprintf(fp,"%d %s ", G.vertices[i].data.key, 
G.vertices[i].data.others);
        i++;
    }
    i=-1;
    fprintf(fp,"%d nil ",i);
    i=0;
    for(i;i<G.vexnum;i++){
        p=G.vertices[i].firstarc;
        while(p){
            fprintf(fp,"%d ",i);
            fprintf(fp,"%d ",p->adjvex);
            p=p->nextarc;
        }
    }
    fprintf(fp,"%d %d",-1,-1);
    fclose(fp);
    return OK;
}
 
int LoadGraph(ALGraph &G, char FileName[])
{//读入文件FileName的图数据,创建图的邻接表
    FILE *fp=fopen(FileName,"r");
    int i=0;
    ArcNode *p,*q;
    VertexType V[31];
    KeyType VR[100][2];
    do{
        fscanf(fp,"%d",&(V[i].key));
        fscanf(fp,"%s",V[i].others);
        G.vertices[i].data=V[i];
        G.vertices[i].firstarc=NULL;
        i++;
    }while(V[i-1].key!=-1);
    G.vexnum=i-1;
    i=0;
    while((fscanf(fp,"%d",&VR[i][0]))){
        if(VR[i][0]==-1) break;
        fscanf(fp,"%d",&VR[i][1]);
        i++;
    }
    VR[i][0]=VR[i][1]=-1;
    i=0;
    while (VR[i][0]!=-1) 
    {
        p=(ArcNode*)malloc(sizeof(ArcNode));
        p->adjvex=VR[i][1];
        p->nextarc=NULL;
        if (G.vertices[VR[i][0]].firstarc==NULL)    
        {
            G.vertices[VR[i][0]].firstarc=q=p;
        } else
        {
            q->nextarc=p;q=p;
        }
        i++;
    }
    fclose(fp);
    return OK;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值