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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM