数据结构课设 图论算法设计智能公交车查询系统

补发一下老东西(未优化)

目录

设计具体内容:

功能模块图:

各模块流程图:

运行效果图:

源码:


设计具体内容:

应用相关数据结构及算法,设计并实现一个具有查询功能的城市公交查询系统。设计其信息数据结构,实现如下功能:

(1)有 2 种或 2 种以上的查询功能选择等;

(2)实现根据公交路线查询出该路公交的全部途经路线,根据站点实现途经该站点的公交线路;

(3)能够实现换乘查询功能,或2 点之间有无公车通过的线路;

(4)实现可以规避某一二个站点的最优线路(良好);

(5)根据手机或者其他设备提供的功能,设计步行、骑行、公交或者驾车等的二个选项,并设计出以最短时间、最短路径优先的推荐路径方案中的二个选项,能根据最优排序结果输出全部公交线路和站点的信息等(优秀)

要求:

(1)理解及熟练运用相关图路径算法;

(2)理解运用运用图的存储;

(3)理解运用相关查询技术;

(4)界面友好、系统运行应该快速、稳定、高效和可靠。


功能模块图:


各模块流程图:


运行效果图:


源码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <stack>
using namespace std;

//邻接矩阵的存储结构
typedef struct Cell
{
  int adj[100];  //存储权值
  
//记录每个站点所经过的公交线路数,在程序中用作标记量
  int adj_loc;
}cell[500][500];

//无向带权图的存储结构
typedef struct map
{
    string vex[500]={"徐工院","汉源国际华城","丽水路","龙湖之家西门","徐州市档案馆","绿地商务城","海顿广场","公园首府","元和路","汉风路","普陀路","彭祖大道"};    
	 //顶点字符串数组
    cell arcs;             //邻接矩阵
    int vexnum,arcnum;     //顶点数量和边的数量
}graph;

graph G;
int road[50] = {1,2,3};//记录公交路线号 
int road_a =3;//记录公交路线数 

//判断顶点是否重复
int vex_repeat(string &point)
{
  int i = 0;
  for(i = 0;i<500;i++)
  {
    if(point == G.vex[i])   //vex顶点 
    return 0;
  }
  return 1;
}


//确定某个顶点 v 在图 G 中的位置
int Locate_vex(string v)
{
  int i;
  for(i = 0;i < 500;i++)
  {
    if(G.vex[i] == v)//string定义中的汉字可以直接比较是否相等 
    return i;
  }
  return -1;
}


//输出图G的顶点
void print_vex()//显示站点 
{
  int num;
  for(num = 0;num < G.vexnum;num++)
  {
    cout<<num<<":"<<G.vex[num]<<endl;
  }
}
 
//输出图G的邻接矩阵
void print_arcs()//显示站点间的公交路线 
{
  int num1,num2,num3;
  for(num1 = 0;num1 < G.vexnum;num1++)
  {
  	cout<<"站点"<<num1<<":"; 
    for(num2 = 0;num2 < G.vexnum;num2++)
    {
	   cout<<"(";
	   for(num3 = 0;num3 < G.arcs[num1][num2].adj_loc;num3++)
       {
          
		  cout<<G.arcs[num1][num2].adj[num3]<<",";
        }
        cout<<")"<<"\t";
    }
     cout<<"*"<<endl;
  }
}

/*起始点*/
//建立顶点的存储结构 
void Create_vex()
{
  for(int k = 12;k < 500;k++)
  {
    G.vex[k] = "0";
  }
  G.vexnum = 12;
  
}
 
//建立邻接矩阵的存储结构
void Creat_arcs()
{
	int sum_arcs = 0;  //记录边的总数
    //对邻接矩阵进行初始化
	for(int i = 0;i<500;i++)
	{
	  for(int j = 0;j < 500;j++)
	  {
	    G.arcs[i][j].adj_loc = 0;
        for(int c = 0;c < 100;c++)
	    {
	       G.arcs[i][j].adj[c] = 0;
	    }
	  }
	}
	   //1号线 
	  G.arcs[1][2].adj[G.arcs[1][2].adj_loc++] = 1;
	  G.arcs[2][3].adj[G.arcs[2][3].adj_loc++] = 1;
	  G.arcs[3][4].adj[G.arcs[3][4].adj_loc++] = 1;
	  G.arcs[4][5].adj[G.arcs[4][5].adj_loc++] = 1;
	  G.arcs[5][6].adj[G.arcs[5][6].adj_loc++] = 1;
	  G.arcs[6][5].adj[G.arcs[6][5].adj_loc++] = 1;
	  G.arcs[5][4].adj[G.arcs[5][4].adj_loc++] = 1;
	  G.arcs[4][3].adj[G.arcs[4][3].adj_loc++] = 1;
	  G.arcs[3][2].adj[G.arcs[3][2].adj_loc++] = 1;
	  G.arcs[2][1].adj[G.arcs[2][1].adj_loc++] = 1;
	  //2号线 
	  G.arcs[1][7].adj[G.arcs[1][7].adj_loc++] = 2;
	  G.arcs[7][3].adj[G.arcs[7][3].adj_loc++] = 2;
	  G.arcs[3][4].adj[G.arcs[3][4].adj_loc++] = 2;
	  G.arcs[4][10].adj[G.arcs[4][10].adj_loc++] = 2;
	  G.arcs[10][11].adj[G.arcs[10][11].adj_loc++] = 2;
	  G.arcs[11][10].adj[G.arcs[11][10].adj_loc++] = 2;
	  G.arcs[10][4].adj[G.arcs[10][4].adj_loc++] = 2;
	  G.arcs[4][3].adj[G.arcs[4][3].adj_loc++] = 2;
	  G.arcs[3][7].adj[G.arcs[3][7].adj_loc++] = 2;
	  G.arcs[7][1].adj[G.arcs[7][1].adj_loc++] = 2;
	  //3号线 
	  G.arcs[0][6].adj[G.arcs[0][6].adj_loc++] = 3;
	  G.arcs[6][8].adj[G.arcs[6][8].adj_loc++] = 3;
	  G.arcs[8][10].adj[G.arcs[8][10].adj_loc++] = 3;
	  G.arcs[10][1].adj[G.arcs[10][1].adj_loc++] = 3;
	  G.arcs[1][10].adj[G.arcs[1][10].adj_loc++] = 3;
	  G.arcs[10][8].adj[G.arcs[10][8].adj_loc++] = 3;
	  G.arcs[8][6].adj[G.arcs[8][6].adj_loc++] = 3;
	  G.arcs[6][0].adj[G.arcs[6][0].adj_loc++] = 3;
	  G.arcnum =14; 
}

//建立图的存储结构
void Creat_graph()
{
  Create_vex();
  Creat_arcs();
}

//判断公交号是否已存在 
int Locate_road(int j)
{
	for(int i=0;i<road_a;i++)
	{
		if(road[i]==j)return 1;
	}
	return -1;
}
//用户手动录入新的站点
void add_vex()//手动输入站点 
{
	string str,str1,str2;
	int num,j;
	int loca1,loca2,loca;
	while(1)
	{
		cout<<"请您输入需要增加的新的站点:"<<endl;
	    cin>>str;
	    loca = Locate_vex(str);
	     if(loca!=-1)
		{
			cout<<"该站点已存在,请重新输入"<<endl;
			continue; 
		}
		else break;
	} 
	
	cout<<"请您输入该站点属于几路公交车"<<endl;
	cin>>num;
	j=Locate_road(num);
	if(j==-1)//新加路线号,更新全局变量 
	{
		road[road_a]=num;
		num++;
	}
	while(1)
	{
		cout<<"请您输入该站点的前一站是:"<<endl;
	    cin>>str1;
	    loca1 = Locate_vex(str1);
	    if(loca1==-1)
		{
			cout<<"该站点不存在,请重新输入"<<endl;
			continue; 
		}
	    cout<<"请您输入该站点的后一站是:"<<endl;
	    cin>>str2;
	    loca2 = Locate_vex(str2);
	    if(loca2==-1)
		{
			cout<<"该站点不存在,请重新输入"<<endl;
			continue; 
		}
		if(loca2!=-1&&loca1!=-1)break;
	 } 
	G.vex[G.vexnum] = str;           //将该站点的信息增加到vex的数组中
	loca1 = Locate_vex(str1);        
	loca2 = Locate_vex(str2);        //定位str1和str2的位置
	//对新增线路增加权值
	G.arcs[loca1][G.vexnum].adj[G.arcs[loca1][G.vexnum].adj_loc++] = num;
	G.arcs[G.vexnum][loca1].adj[G.arcs[G.vexnum][loca1].adj_loc++] = num;
	G.arcs[loca2][G.vexnum].adj[G.arcs[loca2][G.vexnum].adj_loc++] = num;
	G.arcs[G.vexnum][loca2].adj[G.arcs[G.vexnum][loca2].adj_loc++] = num;
	G.vexnum++;                      //站的数量增加
	cout<<"该站点录入成功!"<<endl;
}


//删除现存的站点
void dele_vex()
{
	string str;
	int locale = -1;
	cout<<"请您输入要删除的站点名称:"<<endl;
	cin>>str;
	locale = Locate_vex(str);
	if(locale == -1)
	{
	  cout<<"删除现存站点失败!"<<endl<<"该站点不存在!"<<endl;	
 	}
 	if(locale != 0)
	{
	 	G.vex[locale] = "0";            //将该站点名称清空
	    for(int i = 0;i < G.vexnum;i++)
	    {    
	      for(int j = 0;j < 100;j++)
 	      {
		     G.arcs[locale][i].adj[j] = 0;
		     G.arcs[i][locale].adj[j] = 0;  //将存储站点权值的数组清空
	      }
	    G.arcs[locale][i].adj_loc = 0;
 	    G.arcs[i][locale].adj_loc = 0;     //将表示该站点的权值数量的变量清零
	    }
	    //G.vexnum--;
	    cout<<"删除站点成功!"<<endl;
	}
	
}



void modify_vex()//修改站点名称
{
	string str;
	string str1;
	int loca = -1;
    cout<<"请输入您要修改的站点名称 : "<<endl;
	cin>>str;
	loca = Locate_vex(str);
	if(loca == -1)
	{
	  cout<<"修改站点失败!   "<<"该站点不存在! "<<endl;
	}
	if(loca != -1)
	{
		cout<<"请输入修改后的名称:"<<endl;
        cin>>str1;
	    G.vex[loca] = str1;
	    cout<<"站点修改成功!"<<endl;
	}
	
}


void add_line()//用户手动增加新的公交线路
{
	string st1,st2;
	int linenum;
	int locate1,locate2;
	cout<<"请您输入要在哪两个站点之间增加线路:"<<endl;
	cout<<"请您先输入第一个站点"<<endl;
	cin>>st1;
	cout<<"请您再输入第二个站点"<<endl;
	cin>>st2;
	cout<<"请您输入要增加的线路号数:"<<endl;
	cin>>linenum;
	locate1 = Locate_vex(st1);
	locate2 = Locate_vex(st2);
	G.arcs[locate1][locate2].adj[G.arcs[locate1][locate2].adj_loc++] = linenum;
	G.arcs[locate2][locate1].adj[G.arcs[locate2][locate1].adj_loc++] = linenum;
	cout<<"该站点录入成功!"<<endl;
}
 
//调整站点间的线路号
int modify_adj()
{
	string str1,str2;
	int lint1,lint2;
	int line1,line2;
	cout<<"请输入想要修改线路号的站点"<<endl;
	cout<<"请输入第一个站点:"<<endl;
	cin>>str1;
	cout<<"请输入第二个站点:"<<endl;
	cin>>str2;
	lint1 = Locate_vex(str1);
	lint2 = Locate_vex(str2);               //找到这两个站点在矩阵中的位置
	cout<<"该站点间已经存在的线路号是:";
	int flag = 0;            //作为标记,检查这两站之间是否有线路相通
	int i = 0,j = 0;
	for(int i = 0;i < G.arcs[lint1][lint2].adj_loc;i++)  
	//输出两站点间已经存在的线路号
	{
		cout<<G.arcs[lint1][lint2].adj[i]<<"号 ";
		flag = 1;
	}
	if(flag == 0)
	{
		cout<<"您输入的两站之间不存在线路,请您手动增加线路"<<endl;
		return 0;
	}
	cout<<endl;
	cout<<"请输入想要改动的站点间的线路号"<<endl;
	cin>>line1;
	cout<<"请输入修改后的线路号"<<endl;
	cin>>line2;
	for(int j = 0;j < G.arcs[lint1][lint2].adj_loc;j++)
	{
		if(G.arcs[lint1][lint2].adj[j] == line1)
		{
			G.arcs[lint1][lint2].adj[i] = line2;
			G.arcs[lint2][lint1].adj[i] = line2;
			cout<<"站点的线路号修改成功!"<<endl;
			break;
		}
	
	}
	if(j == G.arcs[lint1][lint2].adj_loc)
	cout<<"您的输入有误!"<<endl;
	return 1;
}


//对图进行运用迪杰斯特拉算法完成换乘搜索
//全局变量的定义
#define INFMAX 500 //路程最大值
bool visit[500];   //标志站点有没有被访问过	
string un_vex ;  //规避站点  
struct load{          
	int vex[500]; //站点顺序 
	int vex_loc;  //站点的总数 
}P[500];       //换乘站点记录 
int D[500];    //所在站点到其他站点的最短路程 
//建立链表结构存储一条线上的顶点完成直达检索
bool direct_path()
{
	string str[road_a][G.vexnum];
	for(int k=0;k<road_a;k++)//
	{
		int a=0;
		for(int i = 0;i<G.vexnum;i++)
	    {
	       for(int j = 0;j<i;j++)
	       {
              for(int c=0;c<G.arcs[i][j].adj_loc;c++)
	          {    
	             if(G.arcs[i][j].adj[c]==road[k])
	             {
	       	        if(a==0&&i<=j){str[k][a]=G.vex[i];cout<<str[k][a]<<",";a++;}
	       	        else if(a==0&&i>j){str[k][a]=G.vex[j];cout<<str[k][a]<<",";a++;}
					for(int h=0;h<a;h++)
					{
						if(G.vex[i]==str[k][h]){str[k][a]=G.vex[j];cout<<str[k][a];a++;break;}
						if(G.vex[j]==str[k][h]){str[k][a]=G.vex[i];cout<<str[k][a];a++;break;}
					}	
				    cout<<str[k][a]<<",";
		         }
	          }
	        }
	    }
	    cout<<endl;
	    str[k][a]="0";
	    
	}
	int i = 0;
	int j = 0;
	string str1;
	string str2;   //起始站
	string str3;   //终点站
	int loca1,loca2,loca3,loca4,temp;
	bool flag1,flag2;
	bool flag = false;
	cout<<"-------最优路线选择------"<<endl;	
	cout<<"请输入您的起始站:";	
	cin>>str2;	
	cout<<"请输入您的终点站:";	
	cin>>str3;
	cout<<"请输入您需要规避的站点(如果没有请输入'无'):";
	cin>>un_vex; 		
	//查找直达线路并作记录	
	for(i = 0;i < road_a;i++)	
	{	
		flag1 = false;	
		flag2 = false;	
		for(j = 0;j < G.vexnum; j++)	
		{	
			if(str2 == str[i][j]&&str2!=un_vex)
			{	
				loca1 = i;	
				loca2 = j;	
				flag1 = true;
			}	
			if(str3 == str[i][j]&&str2!=un_vex)	
			{	
				loca3 = i;	
				loca4 = j;	
				flag2 = true;	
			}	
		}
		
		if((flag1 == true)&&(flag2 == true))//表示直达线路查找成功
		{	
				flag = true;	
				cout<<"该两站点之间存在直达线路"<<endl;	
				cout<<"该线路号为  "<<i+1<<"  号公交线路"<<endl;	
		}
	}
	
	if(flag == false)	
	cout<<"该两站点之间没有直达路线! 即将为您显示换乘公交路线!"<<endl;	
	return flag;     //若falg = false,表示没有直达路线
} 



//最优换乘路线(迪杰斯特拉算法) 
void djc(int v0)
{
	int v,w;
	int un_loc=Locate_vex(un_vex);  //需要规避站点的位置 
	for(v = 0;v < G.vexnum;v++)
	{
		if(v == un_loc)  visit[v]=true;           //对visit数组初始化(标记数组) 
		else visit[v] = false;                             
		if(G.arcs[v0][v].adj_loc <= 0) D[v] =  INFMAX;  //对D数组初始化 (最短路程记录数组) 
		else D[v] = 1;
		for(w = 0;w < G.vexnum;w++)   P[v].vex_loc = 0;   //对P数组初始化(换乘记录数组) 
		if(D[v] < INFMAX)  {P[v].vex[++P[v].vex_loc] = v0;P[v].vex[++P[v].vex_loc] = v;}	
	}
	D[v0] = 0;visit[v0] = true;                    //v0为起点 
	int i,min;                                    //min为到达未访问站点的最短路程 
	for(i = 1;i < G.vexnum;i++)                   //计算起始站到所有站点的最短路径 
	{
		min = INFMAX;
		for(w = 0;w < G.vexnum;w++)
		{
			if(!visit[w])  
			if(D[w] < min) {v = w;min = D[w];}
		}
	visit[v] = true;
	for(w = 0;w < G.vexnum;w++)
	{
		if(!visit[w]&&G.arcs[v][w].adj_loc > 0&&min+1 < D[w] ) 
		{
			D[w]=D[v]+1;
			P[w]=P[v];
			P[w].vex[++P[w].vex_loc] = w;
		}
	}
   }
 }		 
//换乘车的线路	
void Indirect_path()
	
{
	int i,j;
	int loc1,loc2; 
	string str1,str2;
	cout<<"换乘公交路线显示:"<<endl;	
	cout<<"请输入起始站点:  ";	
	cin>>str1;	
	cout<<"请输入终点站:   ";	
	cin>>str2;	
	loc1 = Locate_vex(str1);	
	loc2 = Locate_vex(str2);
	djc(loc1);
	for(i = 2;i <= P[loc2].vex_loc;i++)
	{
		cout<<"前往站点"<<G.vex[P[loc2].vex[i]];
		cout<<"     公交路线号为"<<G.arcs[P[loc2].vex[i-1]][P[loc2].vex[i]].adj[0]<<"号公交路线"<<endl; 
	}
	cout<<endl;

}

int main()
{
	int choose;
    bool choose_flag; //bool型变量只有true或false两个值 
    Creat_graph();
    while(1)
    {
    cout<<"           &欢迎使用公交查询系统&           "<<endl;
    cout<<"********************************************"<<endl;
    cout<<"*            1.显示所有站点信息            *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*        2.显示站点之间的公交路线号        *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*              3.新增站点信息              *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*              4.删除站点信息              *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*              5.修改站点名称              *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*            6.手动增加公交路线            *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*            7.调整站点间的线路            *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*           8.搜索两站之间的路线           *"<<endl;
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*                9.退出程序                *"<<endl; 
    cout<<"*------------------------------------------*"<<endl;
    cout<<"*                  请选择                  *"<<endl;
    cout<<"********************************************"<<endl;
    cin>>choose;
    switch(choose)
    {
      case 1:print_vex();break;
      case 2:print_arcs();break;
      case 3:add_vex();break;
      case 4:dele_vex();break;
      case 5:modify_vex();break;
      case 6:add_line();break;
      case 7:modify_adj();break;
      case 8:
      {
	   choose_flag = direct_path();
       if(choose_flag == false)Indirect_path();
       else break;
	   } 
	   case 9:
	   {
		  cout<<"退出程序"; exit(1);
	   }
      default:cout<<"您的选择有误!"<<endl;
    }
    system("pause");//程序暂停 
	system("cls"); //清屏 
	}
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/Luoxiaobaia/article/details/120343144