收藏 分销(赏)

数据结构课程设计——漳州通讯网架设方案.doc

上传人:仙人****88 文档编号:11004976 上传时间:2025-06-25 格式:DOC 页数:18 大小:756KB 下载积分:10 金币
下载 相关 举报
数据结构课程设计——漳州通讯网架设方案.doc_第1页
第1页 / 共18页
数据结构课程设计——漳州通讯网架设方案.doc_第2页
第2页 / 共18页


点击查看更多>>
资源描述
漳州通讯网架设方案 一、问题描述 设计要求:在漳州n个区域之间建设通讯网络,只需要保证连通即可,求最经济的架设方案。存储结构采用多种。求解算法多种。 该题目需要运用最小生成树来解决,运用两种方法求最小生成树,分别是PRIM算法和KUSCAL算法。最小生成树的代价之和最小,所以是一种最经济的架设方案。通讯网架设方案中的元素有: (1) 顶点个数(漳州区域个数) (2) 边数(区域间的道路个数) (3) 权值(两区域间的距离) 二、功能需求 该程序是解决城市间架设网络问题的,采用邻接表和邻接矩阵进行存储。要求完成以下功能: (1)采用不同的存储方式要求输出不同的存储结果 (2)求最小生成树:采用两种不同方法求解最经济的架设方案,输出两区域及其之间的距离(权) (3)查询:输出所有的顶点和边的个数、输出所有顶点、输出所有边。 (4)增加:增加有效的顶点和边,要求增加的边和顶点不得重复存在。 (5)删除:(a)删除若干个有效的顶点:要求删除的顶点必须存在。 (b)删除若干条边:要求删除的边必须存在 (6)修改:修改若干个顶点名,要求修改的顶点必须存在,且修改后的顶点名不能和已有的顶点名重复,且修改名字后要求修改该顶点对应的边 (7)登录:用户要通过输入用户名和密码登录系统 (8)输入输出:通过文件方式存储了需要信息,修改更新等也同步到文件 三、 实现要点 (1)架设方案中采用邻接矩阵和邻接表进行存储,根据用户的需要选择不同的存储方式 (2)采用Prim算法和kruscal求最小生成树(及最经济的架设方案)Prim算法就是先选择根,把它放入一个集合U中,剩余的顶点放在集合v中。然后选择该顶点与v中顶点之间最小的一条边,以此类推,如果到达最后一个则返回上一个顶点。而kruscal算法是先写出所有顶点,选择权值最小的边,然后写出第二小的,以此类推,最终要有个判断是否生成环,不生成则得到kruscal的最小生成树。 (3)用户可以随意增加区域的顶点数和边数 (4)用户可以删除顶点和边 (5)用户可以更新顶点名,对应系统自动更新边 (6)用户可以查询现有的顶点信息和边信息。 四.定义 1.各类函数说明 Void queryInformation();//查询函数,查询各区域各边信息 Void add1(); //插入新区域和新边 Void Delete_Vertex(); //删除区域(顶点) Void Delete_adj(); //删除边 Void Update(); //更新顶点和边信息 2.用邻接矩阵存储: (1)结构体定义 struct MGraph { char vexs[20]; //定义一个顶点数组 int arcs[20][20]; //二维数组存储关系与权值 int vexnum,arcnum; //顶点数和边数 }; (2)创建邻接矩阵 int creatMGraph(MGraph &G) { char v1,v2; int i,j,w; cout<<"请输入漳州市区域数(顶点数)和总道路的个数(弧的个数):"<<endl; cin>>G.vexnum>>G.arcnum; for(i=0;i!=G.vexnum;i++) { cout<<"输入地区名"<<i+1<<endl; cin>>G.vexs[i]; } for(i=0;i!=G.vexnum;++i) { for(j=0;j!=G.vexnum;++j) { G.arcs[i][j]=int_max; } } for(int k=0;k<G.arcnum;k++) { cout<<"请输入两区域间的距离(权):"<<endl; cin>>v1>>v2>>w; //输入一条边依附的两点及权值 i=localvex(G,v1); j=localvex(G,v2); G.arcs[i][j]=w; G.arcs[j][i]=w; } cout<<"*******************"<<endl; cout<<"图创建成功"<<endl; cout<<"请根据如下进行操作"<<endl; return G.vexnum; } (3)输出邻接矩阵 void MGraphPrint(MGraph G) //输出邻接矩阵 { int i,j; for(i=0;i<G.vexnum;i++) { for(j=0;j<G.vexnum;j++) if(G.arcs[i][j]==int_max) { cout<<"0"<<" "; } else { cout<<G.arcs[i][j]<<" "; } cout<<endl; } } 3.邻接表存储 (1)结构体定义 struct ArcNode //边表,包含权值、顶点信息 { int weight; //该弧中相邻顶点之间的权值 ArcNode *next; //弧尾相同的下一条弧 char info; //该弧信息 }; struct VertexNode //顶点表 { char data; //节点信息 ArcNode *firstedge; //指向第一条依附该节点的弧的指针 }; struct algraph//图的定义 { VertexNode adjlist[max]; //存放顶点表的数组 int vexnum,arcnum; //图的顶点数和边数 }; (2)创建邻接表 void creatadj(algraph &gra,MGraph G) //用邻接表储存图 { int i=0,j=0; ArcNode *arc; for(i=0;i!=G.vexnum;++i) { gra.adjlist[i].data=G.vexs[i]; gra.adjlist[i].firstedge=NULL; } for(i=0;i!=G.vexnum;++i) { for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j]!=int_max&&j!=G.vexnum) { arc=new ArcNode; arc->weight=G.arcs[i][j]; arc->info=G.vexs[j]; arc->next=gra.adjlist[i].firstedge; gra.adjlist[i].firstedge=arc; } } } gra.vexnum=G.vexnum; gra.arcnum=G.arcnum; } (2)输出邻接表 void adjprint(algraph gra,MGraph G) //输出邻接表 { int i; for(i=0;i!=gra.vexnum;++i) { ArcNode *p; p=gra.adjlist[i].firstedge; while(p!=NULL) { cout<<"("<<G.vexs[i]<<","<<p->info<<")"<<p->weight<<" "; p=p->next; } cout<<endl; } } 4.prim算法求最小生成树 void prim(int g[][max],int n,MGraph G)//最小生成树PRIM算法 { int lowcost[max],prevex[max]; //LOWCOST[]存储当前集合U分别到其余各点的最短路径//prevex[]存储最短路径在U中的结点 int i,j,k,min; for(i=1;i<n;i++) //n个顶点,n-1条边 { lowcost[i]=g[0][i]; //初始化 prevex[i]=0; //顶点未加入最小生成树中 } lowcost[0]=0; //标志顶点0加入U集合 for(i=1;i<n;i++) //形成n-1条边的生成树 { min=inf; k=0; for(j=1;j<n;j++) //寻找满足边的一个顶点在U,另一个顶点在v的最小边 if(lowcost[j]<min&&lowcost[j]!=0) { min=lowcost[j]; k=j; } printf("(%c,%c)%d\t",G.vexs[prevex[k]],G.vexs[k],min); //输出最小边 lowcost[k]=0; //顶点k加入U for(j=1;j<n;j++) //修改由顶点k到其他顶点边的权值 if(g[k][j]<lowcost[j]) {lowcost[j]=g[k][j]; prevex[j]=k;} printf("\n"); } } 5.kruscal算法求最小生成树 struct edg { int from;//弧的一结点 int to;//弧的另一结点 int weight;//弧的权 }; int FindRoot(int parent[],int f) { while(parent[f]>0) f=parent[f]; return f; } void kruscal(MGraph G,algraph gra) //最小生成树KUSCAL算法 { edg edgs[20]; int i,j,k=0; for(i=0;i<G.vexnum;i++) for(j=i;j<G.vexnum;j++) { if(G.arcs[i][j]!=9999) { edgs[k].from=i; edgs[k].to=j; edgs[k].weight=G.arcs[i][j]; ++k; } } int x,y,m,n; int vex2,vex1; //分别表示两个顶点所在树的根节点 for(i=0;i<gra.arcnum;i++) parent[i]=0; for(j=0;j<G.arcnum;j++) { m=10000; for(i=0;i<G.arcnum;i++) { if(edgs[i].weight<m) { m=edgs[i].weight; x=edgs[i].from; y=edgs[i].to; n=i;} } vex2=FindRoot(parent,x); vex1=FindRoot(parent,y); edgs[n].weight=10000; if(vex2!=vex1) { parent[vex2]=vex1; cout<<"("<<G.vexs[x]<<","<<G.vexs[y]<<")"<<m; //输出加入的边 cout<<endl; } } } 6.主函数 int main() { cout<<"欢迎来到漳州通讯网管理系统!"<<endl; string Account="zhengyumei"; string Password="123456"; string ac,pa; cout<<"用户名:"; cin>>ac; cout<<"密码:"; cin>>pa; while(ac!=Account||pa!=Password) { cout<<"用户名或密码错误!"<<endl; cout<<"用户名:"; cin>>ac; cout<<"密码:"; cin>>pa; } if(pa==Password&&ac==Account) {int f=0,f1=0; string num; cout<<endl; cout<<" **************************************"<<endl; cout<<" * 1.进入主页面构建架设方案 *"<<endl; cout<<" * 2.查询漳州通讯区域现状 *"<<endl; cout<<" * 3.增加信息 *"<<endl; cout<<" * 4.删除信息 *"<<endl; cout<<" * 5.修改信息 *"<<endl; cout<<" * 6.退出 *"<<endl; cout<<"**************************************"<<endl; cout<<endl; cout<<"请选择您要的菜单:"<<endl; num="1"; while(num=="1"||num=="2"||num=="3"||num=="4"||num=="5"||num=="6") { if(f==0) { cin>>num; } f=0; if(num=="1")//选择1所要实现功能的代码 { algraph gra;//邻接表 MGraph G;//邻接矩阵 int i,j,d,g[20][20]; d=creatMGraph(G);//返回顶点个数 creatadj(gra,G); cout<<"****************************************"<<endl; cout<<"* 1.用邻接矩阵储存: *"<<endl; cout<<"* 2.用邻接表存储: *"<<endl; cout<<"* 3.PRIM算法求最经济的架设方案 *"<<endl; cout<<"* 4.KRUSCAL算法求最经济的架设方案 *"<<endl; cout<<"* 5.返回 *"<<endl; cout<<"****************************************"<<endl; string s; cout<<"请选择菜单:"<<endl; s="1"; while(s=="1"||s=="2"||s=="3"||s=="4"||s=="5") { if(f1==0) {cin>>s; } f1=0; if(s=="1") { cout<<"用邻接矩阵存储为:"<<endl; MGraphPrint(G); } else if(s=="2") { cout<<"用邻接表存储为:"<<endl; adjprint(gra,G); } else if(s=="3") { for(i=0;i<G.vexnum;i++) for(j=0;j<G.vexnum;j++) g[i][j]=G.arcs[i][j]; cout<<"PRIM算法最经济的架设方案为:"<<endl; prim(g,d,G); } else if(s=="4") { cout<<"KRUSCAL算法最经济的架设方案为:"<<endl; kruscal(G,gra); } else if(s=="5") { break; } else//当用户选择菜单不为1234时,容错处理 { while(s!="1"&&s!="2"&&s!="3"&&s!="4") { cout<<"您的输入不正确,请重新选择菜单:"<<endl; cin>>s; f1=1; } } } if(s=="5") { cout<<"请选择菜单:"<<endl; cout<<"**************************************"<<endl; cout<<"* 1.进入主页面构建架设方案 *"<<endl; cout<<"* 2.查询漳州通讯区域现状 *"<<endl; cout<<"* 3.增加信息 *"<<endl; cout<<"* 4.删除信息 *"<<endl; cout<<"* 5.修改信息 *"<<endl; cout<<"* 6.退出 *"<<endl; cout<<"**************************************"<<endl; continue; } } else if(num=="2") {queryInformation(); continue;} else if(num=="3") { add1(); continue; } else if(num=="4") { string n; cout<<"请选择删除对象:"<<endl; cout<<"___1.删除顶点"<<endl; cout<<"___2.删除边"<<endl; cin>>n; if(n=="1") Delete_Vertex(); else if(n=="2") Delete_adj(); continue; } else if(num=="5") { Update(); continue; } else if(num=="6") {return 0; } else {while((num!="1")&&(num!="2")&&(num!="3")&&(num!="4")&&(num!="5")) { cout<<"您的输入不正确,请重新输入!"<<endl; cin>>num; f=1; } } } } return 0; } 四、 演示结果 1. 用户使用初始界面,需输入用户名密码 2. 选择1进入主页面构建架设方案 说明:出现各个区域及其各边信息,可以通过提示选择储存方式和对应的算法求最经济的架设方案。 选择菜单1,2,3,4出现的界面分别如下: 选择1: 选择2: 选择3: 选择4: 3. 选择菜单2进入查询页面如下: 4. 选择菜单3进行插入(假设插入2顶点2个边) 说明:顶点和边信息如果输入不合规范则会提错,插入的顶点和边如果已经存在则不能插入。插入成功后文件增加了顶点和边,如下所示: 5. 选择菜单4进行删除操作 (1)删除顶点 说明:删除顶点不能重复删除已经删除过的顶点,也不能删除原有顶点以外的顶点。删除顶点同时也把对应顶点相连的边删除。 (2)删除边 说明:删除的边必须存在,不能重复删除已经删除的边 6.修改信息 说明:修改顶点的名称,要求所修改的顶点必须存在,修改顶点后对应边也要更新。 7.退出 选择菜单6则结束程序 18
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服