数据结构课程设计_《旅游景区信息管理系统》

sxy.h

#include <iostream>
#include <cstring>
#include <malloc.h>
#include <cstdio>
#define M 100
#define INF 999666333
using namespace std;
 struct Matrix
{
    string Sname;//景区名称,为了解决哈希冲突
    int count;//景点总数量
    int edge;//道路数量
    int m[M][M];//景点邻接矩阵
    string Pname[M];//各个景点的名称
};
struct Scenic
{
   Scenic(): next(NULL){}
    Matrix mat;
   struct Scenic *next;
};
int hash(string name);
void Welcome();//欢迎界面
void create_graph();//创建景区景点图
void print_graph();//输出景点分布(邻接矩阵的形式输出)
void DFS(int c,struct Scenic *p);//深度优先搜索导游线路
void guide_line();//导游线路
void dfs(int i,struct Scenic *p);//递归实现
void check_circuit();//判断回路
void Floyd(int a,int b,struct Scenic *&p);//Floyd算发求最短路
void min_distance();//最短路径、距离
void prime(struct Scenic *&p,string name);//最小生成树(prime算法)
void build_road();//道路修建规划图、
void scenic_message();//浏览所有景区景点信息
void change_sceic_name(struct Scenic *&p);//修改景点名称;
void change_weight(struct Scenic *&p);//修改该景区某条道路上的权值
void increase_number(struct Scenic *&p);//增加该景区小路的数量
void change_information();//修改景区景点信息
void MainFace();//主界面
void returnMainFace();//返回主界面

sxy.cpp

#include <iostream>
#include <cstring>
#include <fstream>
#include <malloc.h>
#include <cstdio>
#include <sstream>
#include <vector>
#include<conio.h>//getch
#include<cstdlib>//清屏函数头文件
#define l 1<<10
#define mod (1<<10)-1
#include "sxy.h"
using namespace std;
Scenic S[10000];
//用哈希表的形式进行建立查找景区名称地址
int hash(string name)
{
    int key=0,t=name.size();
    for(int i=0;i<t;++i)
        key+='0'-name[i];
        key&=mod;
    return key;
}
//创建一个景区(邻接矩阵形式)
void create_graph()
{
	ofstream outFile;  //输出流对象
	outFile.open("景区景点信息表.txt",ios::app);  //将输出流对象和输出文件建立关联
    string name;
    int i,n1,n2,key;
    cout<<"\n*请输入景区的名称:";
    cin>>name;
    getchar();
    key=hash(name);
    Scenic *p=new Scenic,*q=new Scenic;
    q=S[key].next;
    while(q)//不为空时说明该位置存在景区(ASCII可以相同)
    {
        if(q->mat.Sname==name)//名称不能相同,才可以输入景区
          {
             cout<<"该景点名称已存在,重新输入景点名称: ";
             cin>>name;
             getchar();
             key=hash(name);
             q=S[key].next;
             break;
          }
          else
            q=q->next;
    }
    delete q;
    p->mat.Sname=name;
    //包含文件操作
    outFile<<"*****************************************************************"<<endl;
    outFile<<"景区名称为"<<name<<"的景点信息如下"<<endl;
    cout<<"\n*请输入该景区的景点总数目:";
    cin>>p->mat.count;
    outFile<<"该景区的景点总数目为:"<<p->mat.count<<endl;
    cout<<"\n*请输入景区的道路总数目:";
    cin>>p->mat.edge;
    outFile<<"该景区的道路数目为:"<<p->mat.edge<<endl;
    cout<<"\n*请输入道路两边连接的两个景点编号、名称及道路的长度\n";
    outFile<<"*各个道路连接的两个景点编号、名称及道路的长度信息如下:"<<endl;
    memset(p->mat.m,0,sizeof(p->mat.m));
    for(i=1;i<=p->mat.edge;i++)
    {
            cout<<"\n*第 "<<i<<" 条道路\n";
            cout<<"\t-景点 1 编号:";
            cin>>n1;
            outFile<<"************************第"<<i<<"条道路,"<<endl;
            cout<<"\t-景点 1 名称:";cin>>p->mat.Pname[n1];
            outFile<<"景点编号为"<<n1<<"名称为"<<p->mat.Pname[n1]<<endl;
            cout<<"\t-景点 2 编号:";cin>>n2;
            cout<<"\t-景点 2 名称:";cin>>p->mat.Pname[n2];
            outFile<<"景点编号为"<<n2<<"名称为"<<p->mat.Pname[n2]<<endl;
            cout<<"\t-两景点之间的道路长度:";cin>>p->mat.m[n1][n2];
            outFile<<p->mat.Pname[n1]<<"和"<<p->mat.Pname[n2]<<"之间的直接道路长度是"<<p->mat.m[n1][n2]<<endl;
            p->mat.m[n2][n1]=p->mat.m[n1][n2];

    }
    p->next=S[key].next;
    S[key].next=p;
    cout<<"\n*景区创建成功!";
    outFile.close();  //关闭文件
     returnMainFace();
}
//输出景点分布(邻接矩阵的形式输出)
void print_graph()
{
    string name;
    int key,tag=1;
    Scenic *p;
    cout<<"*景区名称:"<<endl;
    cin>>name;
    getchar();
    key=hash(name);
    p=S[key].next;
    if(p==NULL)
     cout<<"\n*景区景点分布图为"<<name<<"的景区查询不成功!\n";
    else
    {
        while(p)
        {
          if(p->mat.Sname==name)//找到的地址不为空,只有名字相同时才,进行输出有关信息
          {
            cout<<"*************查询景区名称为 "<<name<<" 的各景点分布图如下(以邻接矩阵表示): "<<endl;
            for(int i=1;i<=p->mat.count;++i)
            {
                cout<<"景点名称 "<<p->mat.Pname[i];
                for(int j=1;j<=p->mat.count;++j)
                    cout<<' '<<p->mat.m[i][j];
                    cout<<endl;
            }
             tag=0;
             break;
          }
          else
                p=p->next;
        }
        if(tag)
        cout<<"\n*景区景点分布图为"<<name<<"的景区查询不成功!\n";

    }
      returnMainFace();
}
//深度优先搜索导游线路
int visited[100]={0};
int np;//找到的景点个数,用于在递归时找到出口
void DFS(int c,struct Scenic *p)
{
    np++;
    if(np==p->mat.count)
    {
        cout<<p->mat.Pname[c]<<endl;
        returnMainFace();
    }
    else
        cout<<p->mat.Pname[c]<<" --> ";
    visited[c]=1;
     for(int i=1;i<=(p->mat.count);i++)
    {
        if(p->mat.m[c][i]>0&&!visited[i])
        {
              DFS(i,p);
        if(p->mat.count>np)
        {
            cout<<p->mat.Pname[c]<<"-->";
        }
        }
    }
     if(np==p->mat.count)
        returnMainFace();
}
//导游线路
void guide_line()
{
     //checked();
     Scenic *p;
     int key,c,tag=1;
     cout<<"\n*请输入对应景区的名称:";
     string name;
     cin>>name;
     getchar();
     key=hash(name);
    p=S[key].next;
    if(p==NULL)
      cout<<"\n*景区景点分布图(邻接矩阵表示)查询不存在!\n";
    else
    {
        while(p)
        {
            if(p->mat.Sname==name)
            {
                memset(visited,0,sizeof(visited));
                np=0;
                cout<<"输入对应景点的编号"<<endl;
                cin>>c;
                cout<<"*形成的导游线路图(采用深度优先策略)如下所示:\n\n\t";
                DFS(c,p);
                tag=0;
                break;
            }
            else
                p=p->next;
        }
        if(tag)
        cout<<"\n*景区景点分布图为"<<name<<"的景区查询不成功!\n";
     }
    returnMainFace();
}
int DFS_Count;
int vis[100];
void dfs(int i,struct Scenic *p)
{
    vis[i]=1;//标记顶点i被访问
    for(int j=1;j<=p->mat.count;j++)
    {
        if(p->mat.m[i][j]!=0&&vis[j]==0)
            dfs(j,p);
    }
}
//判断回路
void check_circuit()
{
    int key,tag=1;
    Scenic *p;
    string name;
    cout<<"*景区名称:"<<endl;
    cin>>name;
    getchar();
    key=hash(name);
    p=S[key].next;
    if(p==NULL)
     cout<<"\n*景区景点分布图查询不成功!\n";
    else
    {
        while(p)
        {
            if(p->mat.Sname==name)
            {
                memset(vis,0,sizeof(vis));//初始化vis数组,表示一开始所有顶点都未被访问过
                DFS_Count=0;
                for(int i=1;i<=p->mat.count;i++)//深度优先搜索
                {
                    if(vis[i]==0)//如果这个顶点为被访问过,则从i顶点出发进行深度优先遍历
                    {
                        DFS_Count++;//统计调用void dfs(int i);的次数
                        dfs(i,p);
                    }
                }
                if(p->mat.edge+DFS_Count>p->mat.count)//遍历结束,若联通的数量个数加上边的数量个数>节点的数量个数,就判定为有环
                    cout<<"该景区中存在环"<<endl;
                else
                    cout<<"该景区中不存在环"<<endl;
                    tag=0;
                    break;
            }
            else
                p=p->next;
        }
        if(tag)
          cout<<"\n*景区景点分布图查询不成功!\n";
    }
    returnMainFace();
}
//Floyd算发求最短路
void Floyd(int a,int b,struct Scenic *&p)
{
    int i,j,k;
    int A[M][M],path[M][M];
    for(i=1;i<=p->mat.count;i++)//对进行求最短路的矩阵进行处理
    {
        for(j=1;j<=p->mat.count;j++)
        {
        if(p->mat.m[i][j]==0&&i!=j)
             A[i][j]=INF;
        else if(i==j)
            A[i][j]=0;
        else
            A[i][j]=p->mat.m[i][j];
        if(i!=j&&p->mat.m[i][j]<INF)
            path[i][j]=i;
        else
            path[i][j]=-1;
        }
    }
    for(k=1;k<=p->mat.count;k++)
    {
          for(i=1;i<=p->mat.count;i++)
            {
              for(j=1;j<=p->mat.count;j++)
              {
                  if(A[i][j]>A[i][k]+A[k][j])
                  {
                       A[i][j]=A[i][k]+A[k][j];
                       path[i][j]=path[k][j];
                  }
              }
            }
    }
    int apath[M],d;
    if(A[a][b]<INF&&a!=b)
    {
        cout<<"\n*从 "<<p->mat.Pname[a]<<" 到 "<<p->mat.Pname[b]<<" 的最短路径为:";
        k=path[a][b];
        d=0;
        apath[d]=b;
       while(k!=-1&&k!=a)//循环实现记录对应的节点编号
       {
           d++;
           apath[d]=k;
           k=path[a][k];
       }
         d++;
         apath[d]=a;
         cout<<p->mat.Pname[apath[d]];
         cout<<apath[d];
         for(int s=d-1;s>=0;s--)//输出节点名称
         {
            cout<<" --> "<<p->mat.Pname[apath[s]];
             cout<<','<<apath[s];
         }
          cout<<" ,最短距离为:"<<A[a][b]<<endl;
    }
    else if(a==b)
      cout<<"\n*景点编号输入不合法!\n";
    else
     cout<<"\n*这两个景点间不存在路径\n";
}
//最短路径、距离
void min_distance()
{
    Scenic *p;//=new Scenic;
    string name;
    int a,b,key,tag=1;
    cout<<"*景区名称:"<<endl;
    cin>>name;
    getchar();
    key=hash(name);
    p=S[key].next;
    if(p==NULL)
     cout<<"\n*景区分布图查询不成功!\n";
    else
    {
        while(p)
        {
            if(p->mat.Sname==name)
            {
                cout<<"*******下面为该景区的一些信息:"<<endl;
                cout<<"*******景区名称:"<<p->mat.Sname<<endl;
                for(int i=1;i<=p->mat.count;++i)
                {
                    cout<<"编号为 "<<i<<' '<<"的景点名称为 "<<p->mat.Pname[i];
                    for(int j=1;j<=p->mat.count;++j)
                        cout<<' '<<p->mat.m[i][j];
                        cout<<endl;
                }
                cout<<"*请输入要查询的 最短路径和最短距离 的两个景点的编号:\n";
                cout<<"\t-景点 1:";
                cin>>a;
                getchar();
                cout<<"\t-景点 2:";
                cin>>b;
                getchar();
                Floyd(a,b,p);
                tag=0;
                break;
            }
            else
                p=p->next;
        }
        if(tag)
        cout<<"\n*景区景点分布图查询不成功!\n";
    }
        returnMainFace();
}
void prime(struct Scenic *&p,string name)
{
    int A[M][M],a,b,tag=1;
    while(p)
        {
            if(p->mat.Sname==name)
            {
                for(int i=1;i<=p->mat.count;i++)
                {
                    for(int j=1;j<=p->mat.count;j++)
                    {
                        if(p->mat.m[i][j]==0&&i!=j)
                        A[i][j]=INF;
                        else if(i==j)
                        A[i][j]=0;
                        else
                        A[i][j]=p->mat.m[i][j];
                    }
                }
                cout<<"请输入您开始要建造的景点编号";
                cin>>a;
                cout<<"请输入您要完成到的达景点编号";
                cin>>b;
                cout<<"\n*道路修建规划图(prime算法)规划如下:\n";
                int lowcost[M],closest[M],k=0,sum=0,num=0;
                for(int i=1;i<=p->mat.count;++i)
                {
                    lowcost[i]=A[a][i];
                    closest[i]=a;
                }
                for(int i=1;i<p->mat.count;++i)
                {
                    int min=INF;
                    for(int j=1;j<=p->mat.count;++j)
                    {
                        if(lowcost[j]&&(lowcost[j]<min))
                        {
                            min=lowcost[j];
                            k=j;
                        }
                    }
                    if(min<INF)
                    cout<<"\t-修建的第 "<<++num<<" 条路为:景点  "<<p->mat.Pname[closest[k]]<<"  到景点  "<<p->mat.Pname[k]<<"  ,该条道路长度为:"<<min<<endl;
                    sum+=lowcost[k];
                    lowcost[k]=0;
                    if(k==b)
                    {
                        cout<<"从景点  "<<a<<" 到景点  "<<b<<" 的总路径长度为 "<<sum<<endl;
                        break;
                    }
                    for(int j=1;j<=p->mat.count;++j)
                    {
                        if(A[k][j]&&A[k][j]<lowcost[j])
                        {
                            lowcost[j]=A[k][j];
                            closest[j]=k;
                        }
                    }
                }
            tag=0;
            break;
            }
            else
                p=p->next;
        }
        if(tag)
            cout<<"\n*景区景点分布图查询不成功!\n";
}
void build_road()//道路修建规划图、最小生成树(prime算法)
{
    Scenic *p;
     int key;
     cout<<"\n*请输入对应景区的名称:";

     string name;
     cin>>name;
     getchar();
    key=hash(name);
    p=S[key].next;
    if(p==NULL)
      cout<<"\n*景区景点分布图(邻接矩阵表示)查询不存在!\n";
    else
    {
        prime(p,name);
        returnMainFace();
    }
}
void scenic_message()//文件输出所有信息
{
    system("cls");
    char ch[200];
   ifstream inFile; //输入流对象
   inFile.open("景区景点信息表.txt",ios::in);
   while(!inFile.eof())
   {
       inFile.getline(ch,sizeof(ch),'\n');
       cout<<ch<<endl;
   }
   returnMainFace();
}
//修改景点名称;
void change_sceic_name(struct Scenic *&p)
{
    int i;
    string name,rname,str;
    ifstream inFile("景区景点信息表.txt",ios::in);
    vector<string> v;
    cout<<"请输入原先的景点名称: ";
    cin>>name;
    cout<<"请输入要修改后的名称: ";
    cin>>rname;
    for(i=1;i<=p->mat.count;++i)
    {
        if(p->mat.Pname[i]==name)
           {
              p->mat.Pname[i]=rname;
              break;
           }
    }
    while(inFile)
    {
        getline(inFile, str);
        v.push_back(str);
    }
    stringstream stream;
    string result,s,a,r;// std::string result;
    stream << i; //将int输入流
    stream >> r; //从stream中抽取前面插入的int值
    s="景点编号为"+r;
    s+="名称为";
    a=s;
    s+=name;
    a+=rname;
    ofstream outFile("景区景点信息表.txt",ios::out);
    vector<string>::const_iterator it=v.begin();
    for(;v.end()!=it;++it)
    {
       if(*it==s)
        {
            //v.erase(v.begin()+j);
            outFile<<a<<endl;
        }
        else
            outFile<<*it<<endl;
    }
    inFile.close();
    outFile.close();
    cout<<"景点名称修改成功(您可以在主界面下输出景点分布图和者浏览景区信息进行查看,或者直接打开景区文件进行查看"<<endl;
}
void change_weight(struct Scenic *&p)
{
    int weight,weight1,i,x=0,y=0;
    string name1,name2,a,b,str;
    ifstream inFile("景区景点信息表.txt",ios::in);
    vector<string> v;
    cout<<"请输入的该道路上景点1的名称: ";
    cin>>name1;
    cout<<"请输入的该道路上景点2的名称: ";
    cin>>name2;
    cout<<"请输入的该道路上原先的权值: ";
    cin>>weight;
    cout<<"请输入该道路上要修改后的的权值: ";
    cin>>weight1;
    for( i=1;i<=p->mat.count;++i)//修改到程序里面
    {
        if(p->mat.Pname[i]==name1)
            x=i;
        if(p->mat.Pname[i]==name2)
            y=i;
    }
    p->mat.m[x][y]=p->mat.m[y][x]=weight1;
    while(inFile)//下面修改到文件里面
    {
        getline(inFile, str);
        v.push_back(str);
    }
    //outFile<<p->mat.Pname[n1]<<"和"<<p->mat.Pname[n2]<<"之间的直接道路长度是"<<p->mat.m[n1][n2]<<endl;
    stringstream stream,stream1;
    string ss,s,w,w1;// std::string result;
    stream << weight; //将int输入流
    stream >> w; //从stream中抽取前面插入的int值
    stream1 << weight1; //将int输入流
    stream1 >> w1; //从stream中抽取前面插入的int值
    s=name1;ss=name2;
    s+="和";ss+="和";
    s+=name2;ss+=name1;
    s+="之间的直接道路长度是";ss+="之间的直接道路长度是";
    a=s;b=ss;
    s+=w;ss+=w;
    a+=w1;b+=w1;
    ofstream outFile("景区景点信息表.txt",ios::out);
    vector<string>::const_iterator it=v.begin();
    for(;v.end()!=it;++it)
    {
       if(*it==s)
            outFile<<a<<endl;
       else if(*it==ss)
            outFile<<b<<endl;
       else
            outFile<<*it<<endl;
    }
    inFile.close();
    outFile.close();
    cout<<"景点名称修改成功(您可以在主界面下输出景点分布图和者浏览景区信息进行查看,或者直接打开景区文件进行查看"<<endl;
}
void increase_number(struct Scenic *&p)
{
    string name1,name2,str;
    int i,x=0,y=0,weight;
    ifstream inFile("景区景点信息表.txt",ios::in);
    vector<string> v;
    cout<<"请输入小路两旁的1景区";
    cin>>name1;
    cout<<"请输入小路两旁的2景区";
    cin>>name2;
    cout<<"请输入该小路的权值";
    cin>>weight;
    for(i=1;i<=p->mat.count;++i)
    {
        if(p->mat.Pname[i]==name1)
            x=i;
        if(p->mat.Pname[i]==name2)
            y=i;
    }
    p->mat.m[x][y]=p->mat.m[y][x]=weight;
    while(inFile)//下面修改到文件里面
    {
        getline(inFile, str);
        v.push_back(str);
    }
    ofstream outFile("景区景点信息表.txt",ios::out);
     stringstream stream,stream1,stream2;
    string s,s1,ss,num,num1,w,m;
    vector<string>::const_iterator it=v.begin();
    stream<<p->mat.edge;
    stream>>num;
    p->mat.edge+=1;
    stream1<<p->mat.edge;
    stream1>>num1;
    s="该景区的道路数目为:";s1="该景区的道路数目为:";
    s+=num;s1+=num1;
    for(;v.end()!=it;++it)
    {
       if(*it==s)
            outFile<<s1<<endl;
       else
            outFile<<*it<<endl;
    }
    m="************************第"+num1+"条道路,";
    outFile<<m<<endl;
    stream<<x;
    stream>>num;
    stream1<<y;
    stream1>>num1;
    s="景点编号为"+num+"名称为"+name1;
    outFile<<s<<endl;
    s="景点编号为"+num1+"名称为"+name2;
    outFile<<s<<endl;
    stream2<<weight;
    stream2>>w;
    s=name1+"和"+name2+"之间的直接道路长度是"+w;
    outFile<<s<<endl;
    inFile.close();
    outFile.close();
    cout<<"道路添加修改成功(您可以在主界面下输出景点分布图和者浏览景区信息进行查看,或者直接打开景区文件进行查看"<<endl;
}
void change_information()
{
    int tag=1,n,key;
    Scenic *p;
    string name;
    cout<<"输入您要修改的景区名称";
    cin>>name;
    getchar();
    key=hash(name);
    p=S[key].next;
    if(p==NULL)
     cout<<"\n*您要修改的"<<name<<"景区不存在!\n";
    else
    {
        while(p)
        {
          if(p->mat.Sname==name)
          {
              cout<<"*******下面为该景区的一些信息:"<<endl;
              cout<<"*******景区名称:"<<p->mat.Sname<<endl;
              for(int i=1;i<=p->mat.count;++i)
              {
                cout<<"编号为 "<<i<<' '<<"的景点名称为 "<<p->mat.Pname[i];
                for(int j=1;j<=p->mat.count;++j)
                cout<<' '<<p->mat.m[i][j];
                cout<<endl;
              }
              cout<<"请根据提示选择修改*************************"<<endl;;
              cout<<"\t1、修改该景区对应景点的名称;\n";
              cout<<"\t2、修改该景区某条道路上的权值;\n";
              cout<<"\t3、增加该景区小路的数量;\n";
              cout<<"\t0、返回主界面\n";
              cin>>n;
              switch(n)
              {
              case 1:
                  change_sceic_name(p);
                  break;
              case 2:
                  change_weight(p);
                  break;
              case 3:
                  increase_number(p);
                  break;
              case 0:
                  returnMainFace();
                  break;
              }
            tag=0;
            break;
          }
          else
            p=p->next;
        }
        if(tag)
            cout<<"*您要修改的"<<name<<"景区不存在"<<endl;
    }
    returnMainFace();

}
void returnMainFace()
{
    cout<<"\n\t\t\t按任意键返回主菜单... ...";
    getch();
    system("cls");
    MainFace();
}
void Welcome()
{
    cout<<               "\n\n\t\t******欢迎使用景区旅游信息管理系统******\n\n";
    cout<<" \t \t \t 按任意键进入系统... ...";
    getch();
    MainFace();
}
void MainFace()//主界面
{      system("cls");
    cout<<"\n主菜单:\n";
    cout<<"\t1、创建景区景点分布图;\n";
    cout<<"\t2、输出景区景点分布图(邻接矩阵);\n";
    cout<<"\t3、输出导游线路图;\n";
    cout<<"\t4、判断导游线路图有无回路;\n";
    cout<<"\t5、求某个景区景点间的最短路径和最短距离;\n";
    cout<<"\t6、输出道路修建规划图;\n";
    cout<<"\t7、浏览所有景区景点信息;\n";
    cout<<"\t8、修改景区景点信息;\n";
    cout<<"\t0、退出。\n";
    cout<<"\n*请输入操作选择:";
    char c;
    c=getch();
    cout<<c<<endl;
    while(!(c>='0'&&c<='8'))
    {
        cout<<"*输入有误,请重新输入:";
        c=getch();
        cout<<c<<endl;
    }
    switch(c)
    {
        case '1':
            create_graph();break;
        case '2':
             print_graph();break;
        case '3':
            guide_line();break;//导游线路
        case '4':
            check_circuit();break;//判断回路
        case '5':
            min_distance();break;//最短距离
        case '6':
            build_road();break;//最小生成树
        case '7':
            scenic_message();break;//文件的简单操作
        case '8':
            change_information();break;//修改景区
        case '0':
            cout<<"\n\t\t\t*按任意键关闭本系统*\n";
            exit(0);
    }
}

main.cpp

#include <iostream>
#include"sxy.h"
using namespace std;
int main()
{
    Welcome();
    return 0;
}

    原文作者:旅游交通路线问题
    原文地址: https://blog.csdn.net/sxy201658506207/article/details/78860755
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞