• c++数据结构图论创建一个导航图,实现基本功能


    此段代码有两个函数在用的时候得注意一下
    myswitch函数中的一些变量的定义应当随文件输入的地点的数量而改变
    creaud函数来创建一个图,里面调用到两个文件输入,自己得进行创建

    #include <iostream> #include<fstream> #include<stack> #include<iomanip> #define mvnum 50 #define maxint 32767 typedef int status; using namespace std; typedef struct { int point; //地点的索引 string number; //地点编码,可以再文件中随便设置后读入 string placename; //地点的名称 string introduction; //地点的相关介绍 }vex; typedef struct { int realweight; //图的权值,即地点之间的真实距离 int virtualize; //用来存放输出为0和距离的矩阵而已 }arc; typedef struct { vex vexs[mvnum]; //0下标不用 arc arcs[mvnum][mvnum]; int vexnum,arcnum; string title[4]; }Amgraph; status locatvex(Amgraph G,int place) { for(int i=1;i<=G.vexnum;i++) { if(G.vexs[i].point==place) { return i; } } } status creatudn(Amgraph &G) //创建图 这个函数是最重点的函数,要求自己建造一个图,并构建两个文件,分别存放地点和地点之间的联系距离
                      只要数据输入了,其他函数都能够通用。
    { fstream file; file.open("place.txt"); if(!file) { cout<<"open error"<<endl; } int i=1; file>>G.title[0]>>G.title[1]>>G.title[2]>>G.title[3]; while(!file.eof()) //此处在插入数据是一个重点,使用一个txt文件存放对应的数据,用空格隔开,分行存放数据,后通过文件流传值给
                  G.vexs[i].point (地点的索引,从1开始,有n个地点就一直到n) G.vexs[i].number(地点的一个代码编号)
                  G.vexs[i].placename(地点的名称) G.vexs[i].introduction(地点的相关介绍)

    //格式是这样子的

                  
              
    { file
    >>G.vexs[i].point>>G.vexs[i].number>>G.vexs[i].placename>>G.vexs[i].introduction; i++; } file.close(); file.open("path.txt"); if(!file) { cout<<"error open"<<endl; } for(int m=1;m<=G.vexnum;m++) //初始化,必须有 { for(int n=1;n<=G.vexnum;n++) { G.arcs[m][n].realweight=maxint; G.arcs[m][n].virtualize=0; } } int place1,place2,distance,pos1,pos2; while(!file.eof()) //读取输入另一个存放路劲和长度的文件,文件里面每一行放着三个数据 分别是 place1的索引,place2的索引,还有两地的距离
                    表示两地之间有连接并且距离为distance,此处也为一个重点。
     
               
    { file
    >>place1>>place2>>distance; pos1=locatvex(G,place1); pos2=locatvex(G,place2); G.arcs[pos1][pos2].realweight=G.arcs[pos1][pos2].virtualize=distance; G.arcs[pos2][pos1].realweight=G.arcs[pos1][pos2].virtualize=distance; } file.close(); } void updategraph(Amgraph &G) //更新图 ,增加你想加入的东西 { int addvex,addarc,i=G.vexnum+1; cout<<"请输入要增加的点数目:"; cin>>addvex; cout<<"请输入要增加的边的数目:"; cin>>addarc; int origanvexnum=G.vexnum; G.vexnum=G.vexnum+addvex; G.arcnum=G.arcnum+addarc; for(int m=origanvexnum+1;m<=G.vexnum;m++) //给扩展出来的两列初始化。 { for(int n=1;n<=G.vexnum;n++) { G.arcs[m][n].realweight=maxint; G.arcs[n][m].realweight=maxint; G.arcs[m][n].virtualize=0; G.arcs[n][m].virtualize=0; } } while(addvex!=0) //增加点 { cout<<"请输入要增加的点的下标,从"<<G.vexnum-addvex+1<<"开始输入下表,编码,地点名称,和介绍 :"; cin>>G.vexs[i].point>>G.vexs[i].number>>G.vexs[i].placename>>G.vexs[i].introduction; i++; addvex--; } int place1,place2,distance; int pos1,pos2; while(addarc!=0) //更新的时候用到 { cout<<"请输入要增加的边的连接的两个地点的下表以及距离:"; cin>>place1>>place2>>distance; pos1=locatvex(G,place1); pos2=locatvex(G,place2); G.arcs[pos1][pos2].realweight=G.arcs[pos1][pos2].virtualize=distance; G.arcs[pos2][pos1].realweight=G.arcs[pos1][pos2].virtualize=distance; addarc--; } } void outputgraph(Amgraph G) //输出图的所有的相关信息 { cout<<G.title[0]<<" "<<G.title[1]<<" "<<G.title[2]<<setw(40)<<G.title[3]<<endl; for(int i=1;i<=G.vexnum;i++) { cout<<G.vexs[i].point<<setw(10)<<G.vexs[i].number<<" "<<G.vexs[i].placename<<setw(40)<<G.vexs[i].introduction<<endl; } cout<<endl; } void outputgraphudn(Amgraph G) //输出邻接矩阵 { for(int i=1;i<=G.vexnum;i++) { for(int j=1;j<=G.vexnum;j++) { cout<<G.arcs[i][j].virtualize; if(j!=G.vexnum) { cout<<setw(4); } } cout<<endl; } cout<<endl; cout<<G.arcnum<<endl; } void searchplace(Amgraph G) //查找某一地点并且输出相关的信息 { string str; int tip=0; cout<<"输入地点的编号或者地点名称: "; cin>>str; if(str=="0") { return ; } for(int i=1;i<=G.vexnum;i++) { if(str==G.vexs[i].number||str==G.vexs[i].placename) { tip=1; cout<<G.vexs[i].point<<" "<<G.vexs[i].number<<" "<<G.vexs[i].placename<<" "<<G.vexs[i].introduction<<endl; break; } } if(!tip&&str!="0") { cout<<"没有找到此地点!!! 提示:按0可退出查询"<<endl; return searchplace(G); } } status searchplacepoint(Amgraph G) //找到一个地点的下表 { string place; cout<<"请输入起始的地点名称或者编号:"; cin>>place; int tip=0; if(place=="0") { return 0; } for(int i=1;i<=G.vexnum;i++) { if(G.vexs[i].number==place||G.vexs[i].placename==place) { tip=1; return i; } } if(!tip&&place!="0") { cout<<"未找到该地点!!! "<<endl; cout<<"提示输入0可结束搜索"<<endl; return searchplacepoint(G); } } bool S[mvnum+1]; int D[mvnum+1]; int Path[mvnum+1]; void shortpath(Amgraph G,int &point1,int tip,int ppoint1=0) //tip是一个标志点 tip为 的时候用于寻找以point1为起始的路径。 { //tip为0时,用于寻找以ppoint为起点的路径。 if(tip==1) { point1=searchplacepoint(G); } else if(tip==0) { point1=ppoint1; } if(point1==0) { return ; } int n=G.vexnum; for(int point2=1;point2<=n;point2++) { S[point2]=false; D[point2]=G.arcs[point1][point2].realweight; //初始化其他点point2到point1这一点的权值,没有路径则为无穷大。 if(D[point2]<maxint) { Path[point2]=point1; //将每一个与point1存在直接相连的店的Path设为point1 ,没有直接相连则设置-1. } else { Path[point2]=-1; } } S[point1]=true; D[point1]=0; //初始化完毕 int min,point3; for(int i=2;i<=n;i++) { min=maxint; for(int j=1;j<=n;j++) { if(D[j]<min&&!S[j]) { min=D[j]; point3=j; } //找出当前的路径中最小的一段终点是在 point3; } S[point3]=true; for(int j=1;j<=n;j++) { if(!S[j]&&G.arcs[point3][j].realweight+D[point3]<D[j]) //判断是否point3这一点到j这一点的距离和point3到远点point1的距离之和是否小于j到远点point1这一点的距离 { Path[j]=point3; //假设成立的话修改最短路径中j的一个点为point3 D[j]=G.arcs[point3][j].realweight+D[point3]; //修改j到原点point1的距离 } } } cout<<"路径搜索成功!"<<endl; } void allshortpath(Amgraph G) { int point1; shortpath(G,point1,1); cout<<G.vexs[point1].placename<<"到其他地点的路径的最短距离如下"<<endl; for(int point4=1;point4<=G.vexnum;point4++) { cout<<G.vexs[point1].placename<<"-->"<<G.vexs[point4].placename<<"的距离:"<<D[point4]<<endl; } cout<<G.vexs[point1].placename<<"到其他地点的最短路径如下"<<endl; for(int point4=1;point4<=G.vexnum;point4++) { int point5=point4; int count=0; string temp[50]; while(D[point5]!=0) //如果终点 { temp[count]=G.vexs[Path[point5]].placename; point5=Path[point5]; count++; } if(D[point4]==0) //如果终点是原点的话就直接输出一个原点 { cout<<G.vexs[point5].placename<<endl; } else { for(int i=count-1;i>=0;i--) { cout<<temp[i]<<"-->"; } cout<<G.vexs[point4].placename<<endl; //point4这个点为终点,它的地名没有存进数组里面,故需要将其输出,否则失去终点。 } //此时不能用point5,因为point5已经改变了。 } } status searchplacepoint(Amgraph G,string place) { for(int i=1;i<=G.vexnum;i++) { if(G.vexs[i].number==place||G.vexs[i].placename==place) { return i; } } } void errorexcept(Amgraph G,string &place) //排除异常的输入并且给出重新输入的机会。 { int tip=0; for(int i=1;i<=G.vexnum;i++) { if(G.vexs[i].number==place||G.vexs[i].placename==place) { tip=1; return ; } } if(!tip) { cout<<"输入错误,未找到该地点,请重新输入: "; cin>>place; return errorexcept(G,place); } } void twoplacepath(Amgraph G) //查询两个地点之间的联系 { string place1,place2; cout<<"请输入起始地点: " ; cin>>place1; errorexcept(G,place1); cout<<"请输入终点: "; cin>>place2; errorexcept(G,place2); int p1,p2,viturized; //viturized是无所谓的变量 p1=searchplacepoint(G,place1); p2=searchplacepoint(G,place2); shortpath(G,viturized,0,p1); //viturized是无所谓的变量。 cout<<G.vexs[p1].placename<<"-->"<<G.vexs[p2].placename<<"的距离:"<<D[p2]<<endl; int point5=p2; int count=0; string temp[50]; while(D[point5]!=0) //将路径的倒数第一个放进下标为1的数组中,一次放入 { temp[count]=G.vexs[Path[point5]].placename; point5=Path[point5]; count++; } for(int i=count-1;i>=0;i--) { cout<<temp[i]; cout<<"-->"; } cout<<G.vexs[p2].placename<<endl; //输出到达的目的地 } void creatmenu() //创建菜单 { cout<<endl; cout<<"---------------菜单---------------"<<endl; cout<<"1:创建导航地图"<<endl; cout<<"2:输出地图的各个地方信息"<<endl; cout<<"3:输出地图的邻接矩阵"<<endl; cout<<"4:查找地点的相关信息"<<endl; cout<<"5:查找某地点到其他所有地点的最短路径以及距离"<<endl; cout<<"6:查找两地点间的信息"<<endl; cout<<"7:增加地图地点"<<endl; cout<<"0:退出导航系统"<<endl; cout<<"----------------------------------"<<endl; cout<<endl; } void checkfunction(int &choice) //检查输入的功能有没有错误 这个函数也有一部分不能通用的,比如下面边的数目的定义和定点的数量的定义,53和30,如果上面文件输入的数目不够的话得做出适当的改变 { int tip=0; for(int i=0;i<=7;i++) { if(choice==i) { tip=1; return ; } } if(!tip) { cout<<"输入错误,请重新输入:"; cin>>choice; } } void myswitch() { Amgraph G; G.arcnum=53; G.vexnum=30; int choice=1; while(choice) { switch(choice) { case 1:creatudn(G);cout<<"创建导航地图成功"<<endl; break; case 2:outputgraph(G); break; case 3:outputgraphudn(G); break; case 4:searchplace(G); break; case 5:allshortpath(G); break; case 6:twoplacepath(G); break; case 7:updategraph(G); break; default :break; } creatmenu(); cout<<"请选择功能: "; cin>>choice; checkfunction(choice); if(choice==1) { cout<<"已经创建地图"<<endl; creatmenu(); cout<<"请重新选择功能: "; cin>>choice; } } if(choice==0) { return ; } } int main() { myswitch(); return 0; }

    G.vexs[i].point
  • 相关阅读:
    C#设计模式-原型模式
    C#设计模式-建造者模式
    c#设计模式-组合模式
    c#设计模式-适配器模式
    c#设计模式-命令模式
    c#设计模式-观察者模式
    c#设计模式-工厂方法
    C#设计模式-简单工厂
    C#设计模式-工厂模式
    C#设计模式-单例模式
  • 原文地址:https://www.cnblogs.com/chenhanwu/p/9753860.html
Copyright © 2020-2023  润新知