typedef struct arcell 息 {
int adj; }arcell,adjmatrix[MaxVertexNum][MaxVertexNum]; 矩阵类型
typedef struct vexsinfo { int position; char name[32]; 称
char introduction[256]; //边的权值信 //权值
//图的邻接//顶点信息 //景点的编号 //景点的名
//景点的介绍 }vexsinfo;
typedef struct mgraph //图结构信息 {
vexsinfo vexs[MaxVertexNum]; (数组) adjmatrix arcs;
int vexnum,arcnum; 顶点数和边数 }mgraph;
//全局变量
int visited[35]; 否已经访问过
int d[35]; 权值或存储路径顶点编号
mgraph campus; (大学校园)
//顶点向量
//邻接矩阵 //分别指定
//用于标志是 //用于存放 //图变量
// (1) 对图初始化
mgraph initgraph() {
int i=0,j=0; mgraph c;
c.vexnum =24; //顶点个数 c.arcnum =33; //边的个数 for(i=0;i c.vexs[i].position =i; //依次输 入顶点信息 strcpy(c.vexs[0].name ,\"学校南正门\"); strcpy(c.vexs[0].introduction ,\"学校大门、学校班车进出口\"); strcpy(c.vexs[1].name ,\"主教学楼\"); strcpy(c.vexs[1].introduction ,\"软件学院,经管学院等的教学主 楼\"); strcpy(c.vexs[2].name ,\"南门草坪\"); strcpy(c.vexs[2].introduction ,\"学校最大的草坪就在门口右边\"); strcpy(c.vexs[3].name ,\"软件学院办公楼\"); strcpy(c.vexs[3].introduction ,\"发课本,法律咨询处,办公处\"); strcpy(c.vexs[4].name,\"人文学院\"); strcpy(c.vexs[4].introduction ,\"文学院,楼高层,并且一楼是机 房\"); strcpy(c.vexs[5].name ,\"原始山\"); strcpy(c.vexs[5].introduction ,\"未经人工改造的小山,上面只有 一个水塔\"); \"); strcpy(c.vexs[7].name ,\"学生食堂\"); strcpy(c.vexs[7].introduction ,\"高四层,前三层分别是一,二, strcpy(c.vexs[6].name,\"学生宿舍群一\"); strcpy(c.vexs[6].introduction ,\"最新的学生宿舍,生活设施先进 三食堂,第四层是羽毛球,桌球等场地\"); strcpy(c.vexs[8].name, \"家属楼\"); strcpy(c.vexs[8].introduction , \"退休教授居所,有历史韵味\"); strcpy(c.vexs[9].name ,\"图书馆\"); strcpy(c.vexs[9].introduction ,\"学校的早期建筑之一,最近正在 改建\"); strcpy(c.vexs[10].name ,\"学生宿舍群二\"); strcpy(c.vexs[10].introduction ,\"第二建立的宿舍,生活设施较 好,旁边是京九线\"); strcpy(c.vexs[11].name ,\"学生宿舍群三\"); strcpy(c.vexs[11].introduction ,\"学校最早的宿舍,设施较老,楼 高层,地下层\"); strcpy(c.vexs[12].name ,\"学生活动区\"); strcpy(c.vexs[12].introduction ,\"有超市,各个通信营业厅,交电 所,还有提供邮递业务\"); strcpy(c.vexs[13].name ,\"科技楼\"); strcpy(c.vexs[13].introduction ,\"软件学院学生上机的地方,设施 先进\"); strcpy(c.vexs[14].name ,\"浴室\"); strcpy(c.vexs[14].introduction ,\"冬季学生沐浴,打开水的地方, 当然也有理发店\"); strcpy(c.vexs[15].name ,\"足球场\"); strcpy(c.vexs[15].introduction ,\"很正规的足球场,八一衡源足球 队训练专用场\"); strcpy(c.vexs[16].name ,\"露天篮球场\"); strcpy(c.vexs[16].introduction ,\"很大型的一个球场,新生军训就 是在这个地方\"); strcpy(c.vexs[17].name ,\"新体育场\"); strcpy(c.vexs[17].introduction ,\"今年刚刚落成的体育场\"); strcpy(c.vexs[18].name ,\"交大驾校\"); \"); strcpy(c.vexs[18].introduction ,\"华东交大自己的驾校\"); strcpy(c.vexs[19].name ,\"成人继续教育学院\"); strcpy(c.vexs[19].introduction ,\"为成年人提供继续学习的机会 strcpy(c.vexs[20].name ,\"轨道交通学院\"); strcpy(c.vexs[20].introduction ,\"交大最早的学院,为上海交大分 部\"); strcpy(c.vexs[21].name ,\"詹天佑铜像\"); strcpy(c.vexs[21].introduction ,\"在轨道交通学院前面,记念詹天 佑为中国交通事业作出的贡献\");//依次输入边上的权值信息 strcpy(c.vexs[22].name ,\"风雨室内篮球场\"); strcpy(c.vexs[22].introduction ,\"封闭的篮球场管,同是也是学校 武术队的训练场地\"); strcpy(c.vexs[23].name ,\"大礼堂\"); strcpy(c.vexs[23].introduction ,\"举行重大活动的场地\"); for(i=0;i //部分弧长 c.arcs[0][1].adj=200; c.arcs[1][3].adj=50; c.arcs[2][5].adj=18; c.arcs[2][6].adj=380; c.arcs[6][9].adj=560; c.arcs[5][9].adj=430; c.arcs[20][21].adj=50; c.arcs[21][0].adj=110; c.arcs[13][15].adj=1800; c.arcs[20][15].adj=1700; c.arcs[15][13].adj=20; c.arcs[0][2].adj=10; c.arcs[11][13].adj=130; c.arcs[11][20].adj=320; c.arcs[1][4].adj=50; c.arcs[3][7].adj=67; c.arcs[4][8].adj=71; c.arcs[7][8].adj=53; c.arcs[7][11].adj=120; c.arcs[7][10].adj=250; c.arcs[10][14].adj=180; c.arcs[10][12].adj=153; c.arcs[11][12].adj=208; c.arcs[12][13].adj=480; c.arcs[9][19].adj=70; c.arcs[9][16].adj=30; c.arcs[19][16].adj=20; c.arcs[17][18].adj=440; c.arcs[19][20].adj=1300; c.arcs[19][20].adj=580; c.arcs[21][22].adj=60; c.arcs[20][23].adj=51; c.arcs[21][23].adj=30; for(i=0;i return c; }//initgraph // (2) 查找景点在图中的序号 //邻接矩 int locatevex(mgraph c,int v) { int i; for(i=0;i return i; //找到,返回顶点序 号i return -1; //否则,返回-1 } //(3) 、(4) 求两景点间的所有路径 // (3) 打印序号为m,n景点间的长度不超过个景点的路径 void path(mgraph c, int m,int n,int k) { int s,x=0; int t=k+1; //t 记载路径上 下一个中间顶点在d[]数组中的下标 if(d[k]==n && k<8) //d[k]存储路径 顶点。若d[k]是终点n且景点个数<=8,则输出该路径 { //递归出口,找 到一条路径 for(s=0;s 为起点m printf(\"%s\",c.vexs[d[s]].name); //输出最后一个景点名(即顶点n的名字,此时s==k) printf(\"\\n\\n\"); } else { s=0; while(s visited[s]=1; d[k+1]=s; //存储顶点编号s 至d[k+1]中 path(c,m,n,t); //求从下标为t=k+1的第d[t]个顶 点开始的路径(递归调用),同时打印出一条m至n的路径 visited[s]=0; //将找到的路径上顶点的访问标 志重新设置为,以用于试探新的路径 } s++; //试探从下一个顶点s 开始是 否有到终点的路径 }//endpath //(4) 打印两景点间的景点个数不超过的所有路径。调用(3) int allpath(mgraph c) { int k,i,j,m,n; printf(\"\\n\\n请输入你要查询的两个景点编号:\\n\\n\"); scanf(\"%d%d\",&i,&j); printf(\"\\n\\n\"); m=locatevex(c,i); //调用(2),确定该顶 }//endwhile }//endelse 点是否存在。若存在,返回该顶点编号 n=locatevex(c,j); d[0]=m; //存储路径起点m (int d[]数组是全局变量) for(k=0;k path(c,m,n,0); //调用(3)。k=0,对应起点d[0]==m。k为d[]数组下标 return 1; } // (5) 用迪杰斯特拉算法,求出一个景点到其他景点间的最短路径,并打印 void shortestpath_dij(mgraph c) { //迪杰斯特拉算法,求从顶点v0最短路经上的顶点到其余顶点的最短路经及其带权长度d[v] //若p[v][w]为,则w是从v0到v的 //final[v]类型用于设置访问标志 int v,w,i,min,t=0,x,flag=1,v0; //vo为起始景点的 编号 int final[35],d[35],p[35][35]; printf(\"\\n请输入一个起始景点的编号:\"); scanf(\"%d\",&v0); printf(\"\\n\\n\"); while(v0<0||v0>c.vexnum) { printf(\"\\n你所输入的景点编号不存在\\n\"); printf(\"请重新输入:\"); scanf(\"%d\",&v0); }//while for(v=0;v d[v]=c.arcs[v0][v].adj; 的权值赋值给d[v] for(w=0;w //初始化p[][] 数组,各顶点间的路径全部设置为空路径 p[v][w]=0; if(d[v] p[v][v]=1; 自己要连通 } }//for d[v0]=0; 的权值设为 final[v0]=1; 志设为,v 属于s 集 for(i=1;i //v0的访问标 //对其余 //在未被访问 //v0 到w (有边) 的权值 final[v]=1; //v 的访问 标志设置为,v 属于s集 for(w=0;w if(!final[w]&&(min+c.arcs[v][w].adj d[w]=min+c.arcs[v][w].adj; //修改v0 到w 的权值d[w] for(x=0;x p[w][x]=p[v][x]; p[w][w]=1; }//if }//for for(v=0;v { if(v!=v0) printf(\"%s\",c.vexs[v0].name); //输出景点v0 的景点名 for(w=0;w if(p[v][w] && w!=v0 && w!=v) //若w 是且 w 不等于v0,则输出该景点 } printf(\"---->%s\",c.vexs[v].name); printf(\"\\n总路线长为%d米\\n\\n\",d[v]); printf(\"--->%s\",c.vexs[w].name); }//for }//shortestpath //(6)-(11)修改图的信息。包括建图、更新信息、删除、增加结点和边 //(6) 构造图的邻接矩阵 int creatgragh(mgraph &c) //建图。以图的邻接矩阵存储图 { int i,j,m,n; int v0,v1; int distance; printf(\"请输入图的顶点数和边数: \\n\"); scanf(\"%d %d\",&c.vexnum ,&c.arcnum ); printf(\"下面请输入景点的信息:\\n\"); for(i=0;i scanf(\"%s\",c.vexs[i].name ); printf(\"\\n请输入景点的简介:\"); scanf(\"%s\",c.vexs[i].introduction ); } //构造顶点向 for(i=0;i printf(\"下面请输入图的边的信息:\\n\"); for(i=1;i<=c.arcnum ;i++) { printf(\"\\n第%d条边的起点终点长度为:点、终点及权值 scanf(\"%d %d %d\",&v0,&v1,&distance); m=locatevex(c,v0); n=locatevex(c,v1); if(m>=0 && n>=0) { c.arcs[m][n].adj =distance; c.arcs[n][m].adj =c.arcs[m][n].adj ; } } return 1; }//creatgragh //构造邻接矩阵 ,i);//输入一条边的起 \" // (7) 更新图的部分信息。返回值: 1 int newgraph(mgraph &c) { int changenum; 记录要修改的对象的个数 int i,m,n,t,distance,v0,v1; printf(\"\\n下面请输入你要修改的景点的个数:\\n\"); scanf(\"%d\",&changenum); while(changenum<0||changenum>c.vexnum ) { printf(\"\\n输入错误!请重新输入\"); scanf(\"%d\",&changenum); } for(i=0;i scanf(\"%s\",c.vexs[t].name ); printf(\"\\n请输入景点的简介:\"); scanf(\"%s\",c.vexs[t].introduction ); } printf(\"\\n下面请输入你要更新的边数\"); scanf(\"%d\",&changenum); while(changenum<0||changenum>c.arcnum ) { printf(\"\\n输入错误!请重新输入\"); scanf(\"%d\",&changenum); } printf(\"\\n下面请输入更新边的信息:\\n\"); for(i=1;i<=changenum ;i++) { printf(\"\\n修改的第%d条边的起点终点长度为: scanf(\"%d %d %d\",&v0,&v1,&distance); m=locatevex(c,v0); n=locatevex(c,v1); if(m>=0&&n>=0) { ,i); \" c.arcs[m][n].adj =distance; c.arcs[n][m].adj =c.arcs[m][n].adj ; } } return 1; }//newgraph // (8) 增加一条边。返回值: int enarc(mgraph&c) { int m,n,distance; printf(\"\\n请输入边的起点和终点编号,权值: scanf(\"%d %d %d\",&m,&n,&distance); while(m<0||m>c.vexnum ||n<0||n>c.vexnum ) { printf(\"输入错误,请重新输入:\"); scanf(\"%d %d\",&m,&n); } if(locatevex(c,m)<0) { printf(\"此结点%d已删除\",m); ); \" return 1; } if(locatevex(c,n)<0) { printf(\"此结点%d已被删除:\",n); return 1; } c.arcs[m][n].adj =distance; c.arcs[n][m].adj =c.arcs[m][n].adj; return 1; }//enarc // (9) 增加一个结点。返回值: int envex(mgraph&c) { int i; printf(\"请输入你要增加结点的信息:\"); printf(\"\\n编号:\"); scanf(\"%d\",&c.vexs[c.vexnum ].position ); printf(\"名称:\"); scanf(\"%s\",c.vexs[c.vexnum ].name ); //对称赋值 printf(\"简介:\"); scanf(\"%s\",c.vexs[c.vexnum ].introduction) ; c.vexnum ++; for(i=0;i c.arcs [c.vexnum -1][i].adj=Infinity; 的一行) c.arcs [i][c.vexnum -1].adj=Infinity; 的一列) } return 1; }//envex // (10) 删除图的一个顶点。返回值: int delvex(mgraph&c) { int i=0,j; int m; int v; if(c.vexnum <=0) //最后一行(新增 //最后一列(新增 { } printf(\"\\n下面请输入你要删除的景点编号:\"); scanf(\"%d\",&v); while(v<0||v>c.vexnum ) { } m=locatevex(c,v); if(m<0) { } for(i=m;i 的操作 { strcpy(c.vexs[i].name ,c.vexs [i+1].name ); strcpy(c.vexs[i].introduction ,c.vexs [i+1].introduction ); } //对原邻接矩阵,删除该顶点到其余顶点的邻接关系。分别删除相 应的行和列 for(i=m;i 依次往前移一行。即删除第m 行 for(i=m;i c.vexnum --; return 1; }//delvex //(11) 删除图的一条边。返回值: int delarc(mgraph&c) { int m,n; int v0,v1; if(c.arcnum <=0) { } printf(\"\\n下面请输入你要删除的边的起点和终点编号:\"); scanf(\"%d %d\",&v0,&v1); printf(\"图中已无边,无法删除。\"); return 1; m=locatevex(c,v0); if(m<0) { } n=locatevex(c,v1); if(n<0) { } c.arcs [m][n].adj =Infinity; //修改邻接矩阵对应的printf(\"此%d 顶点已删除\",v1); return 1; printf(\"此%d 顶点已删除\",v0); return 1; 权值 c.arcs [n][m].adj =Infinity; c.arcnum --; return 1; }//delarc // (12) 输出图的邻接矩阵的值 void printmatrix(mgraph c) { int i,j,k=0; 换行 for(i=0;i else printf(\"%4d\",c.arcs[i][j].adj); k++; if(k%c.vexnum ==0) printf(\"\\n\"); } }//printpath //k 用于计数,控制 //(13)图操作的主调函数。返回值: int changegraph(mgraph &c) { int yourchoice; printf(\"\\n请问是要\\n\\n(1)再次建图 (2)删除结点 (3)删除边\\n\"); printf(\"\\n(4)增加结点 (5)增加边 (6)更 新信息\\n\\n (7)返回?\\n\\n\"); scanf(\"%d\",&yourchoice); printf(\"\\n\\n\"); while(!(yourchoice==1||yourchoice==2||yourchoice==3||yourchoice= =4||yourchoice==5||yourchoice==6 { } while(1) printf(\"输入选择不明确,请重输\\n\"); scanf(\"%d\",&yourchoice); ||yourchoice==7)) { switch(yourchoice) { } case 1: creatgragh(c); break; case 2: delvex(c); case 3: delarc(c); case 4: envex(c); case 5: enarc(c); break; break; break; break; case 6: newgraph(c); break; case 7: return 1; printf(\"\\n请问是要\\n\\n(1)再次建图 (2)删除结点 (3)删除边\\n\"); printf(\"\\n(4)增加结点 (5)增加边 (6)更新信息\\n\\n(7)返回?\\n\\n\"); scanf(\"%d\",&yourchoice); printf(\"\\n\\n\"); while(!(yourchoice==1||yourchoice==2||yourchoice==3||yourchoice= =4||yourchoice==5||yourchoice==6 ||yourchoice==7||yourchoice==8)) { } printf(\"输入选择不明确,请重输\\n\"); scanf(\"%d\",&yourchoice); }//endwhile(1) return 1; }//changegraph // (14) 查询两景点间的最短路径 void shortestpath_floyd(mgraph c) { //用floyd算法求各对顶点v和w间的最短路经及其带权长度的 d[v][w]。 int i,j,k,d[35][35],p[35][35][35]; int v,u,w; for(v=0;v for(w=0;w 权值 for(u=0;u p[v][w][u]=0; if(d[v][w] 顶点 p[v][w][w]=1; // w 是v 至w 最短路径上 的顶点 for(u=0;u }//endfor 点u,试探其是否为v至w最短路径上的顶点 { for(v=0;v for(i=0;i d[v][w]=d[v][u]+d[u][w]; //修改v 至w 的最短路径长 组。若i是v至u的最短路径上的顶点, p[v][w][i]=p[v][u][i]||p[u][w][i]; //或i是u至w的最短 路径上的顶点, 则i是v至w的最短路径上的顶点 } }//endfor printf(\"\\n请输入出发点和目的地编号:\"); scanf(\"%d%d\",&k,&j); printf(\"\\n\\n\"); while(k<0||k>c.vexnum||j<0||j>c.vexnum) { } printf(\"\\n你所输入的景点编号不存在!\"); printf(\"\\n请重新输入出发点和目的地编号:\\n\\n\"); scanf(\"%d%d\",&k,&j); printf(\"\\n\\n\"); printf(\"%s\",c.vexs[k].name ); //输出出发景点名称 for(u=0;u 间景点名称 printf(\"--->%s\",c.vexs[u].name ); printf(\"--->%s\",c.vexs[j].name ); printf(\"\\n\\n\\n总长为%d米\\n\\n\\n\",d[k][j]); }//shortestpath_floyd // (15) 查询景点的信息 void seeabout(mgraph c) { int k; printf(\"\\n请输入要查询的景点编号:\"); scanf(\"%d\",&k); while(k<0||k>c.vexnum) //输出目的地景点名称 { } printf(\"\\n\\n编号:%-4d\\n\",c.vexs[k].position ); printf(\"\\n\\n景点名称:%-10s\\n\",c.vexs[k].name ); printf(\"\\n\\n介绍:%-80s\\n\\n\",c.vexs[k].introduction ); printf(\"\\n你所输入的景点编号不存在!\"); printf(\"\\n请重新输入:\"); scanf(\"%d\",&k); }//seeabout // (16) 显示所有景点信息 void browsecompus(mgraph c) { int i; printf(\" \\n\\n编号 景点名称 简介\\n\"); printf(\"__________________________________________________ _________________________________________________________\\n\"); for(i=0;i printf(\"__________________________________________________ _________________________________________________________\\n\\n\"); }//browsecompus // (17) 主要工作函数。操作区用户界面 void mainwork() { int yourchoice; campus=initgraph(); printf(\"\\n----------------------------欢迎使用校园导游程序 -----------------------------\\n\"); printf(\"\\n 欢迎来到华东交通大学! \\n\\n\"); printf(\"\\n 菜单选择 \\n\\n\"); printf(\" 1. 学校景点介绍 2. 查看游览路线 \\n\"); printf(\" 3. 查询景点间最短路径 4. 景点信息查询 \\n\"); printf(\" 5. 更改图信息 6. 查询景点间可行路径 \\n\"); printf(\" 7. 退 出 \\n\"); printf(\"\\n------------------------------------------------------------------------- ----\\n\"); printf(\"请输入你的选择:\"); scanf(\"%d\",&yourchoice); while(!(yourchoice==1||yourchoice==2||yourchoice==3||yourchoice= =4||yourchoice==5||yourchoice==6 { } while(1) { switch(yourchoice) printf(\"输入选择不明确,请重输\\n\"); scanf(\"%d\",&yourchoice); ||yourchoice==7)) { case 1: system(\"cls\"); browsecompus(campus); break; case 2: system(\"cls\"); shortestpath_dij(campus); break; case 3: system(\"cls\"); shortestpath_floyd(campus); break; case 4: system(\"cls\"); seeabout(campus); break; break; case 5: system(\"cls\"); changegraph(campus); case 6: system(\"cls\"); allpath(campus); break; case 7: system(\"cls\"); exit(0); break; printf(\"\\n----------------------------欢迎使用校园导游程序 } default: break; -----------------------------\\n\"); printf(\"\\n 欢迎来到华东交 通大学! \\n\\n\"); printf(\"\\n 菜单选择 \\n\\n\"); printf(\" 1. 学校景点介绍 2. 查看游览路线 \\n\"); printf(\" 3. 查询景点间最短路径 4. 景点信息查询 \\n\"); printf(\" 5. 更改图信息 6. 查询景点间可行路径 \\n\"); printf(\" 7. 退 出 \\n\"); printf(\"\\n-----------------------------------------------------------------------------\\n\"); }//mainwork printf(\"\\n请输入你的选择:\"); scanf(\"%d\",&yourchoice); }//endwhile(1) // (18) 主函数。设定界面的颜色大小,调用工作区模块函数 void main() { system(\"color 1f\"); //屏幕颜色设定 system(\"mode con: cols=140 lines=130\"); mainwork(); } 因篇幅问题不能全部显示,请点此查看更多更全内容