数据结构课程设计之图的遍历和生成树求解_第1页
数据结构课程设计之图的遍历和生成树求解_第2页
数据结构课程设计之图的遍历和生成树求解_第3页
数据结构课程设计之图的遍历和生成树求解_第4页
数据结构课程设计之图的遍历和生成树求解_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

##大学数据结构课程设计报告题目: 图的遍历和生成树求解 院(系): 计算机工程学院 学生姓名: 班级:学号: 起迄日期: 2023.6.20 指导教师: 2023—2023年度第2学期一、需求分析1.问题描述:图的遍历和生成树求解实现图是一种较线性表和树更为复杂的数据结构。在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素也许和下一层中多个元素(及其孩子结点)相关但只能和上一层中一个元素(即双亲结点)相关;而在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都也许相关。生成树求解重要运用普利姆和克雷斯特算法求解最小生成树,只有强连通图才有生成树。2.基本功能1)先任意创建一个图;2)图的DFS,BFS的递归和非递归算法的实现3)最小生成树(两个算法)的实现,求连通分量的实现4)规定用邻接矩阵、邻接表等多种结构存储实现3.输入输出输入数据类型为整型和字符型,输出为整型和字符二、概要设计设计思绪:a.图的邻接矩阵存储:根据所建无向图的结点数n,建立n*n的矩阵,其中元素全是无穷大(int_max),再将边的信息存到数组中。其中无权图的边用1表达,无边用0表达;有全图的边为权值表达,无边用∞表达。b.图的邻接表存储:将信息通过邻接矩阵转换到邻接表中,即将邻接矩阵的每一行都转成链表的形式将有边的结点进行存储。c.图的广度优先遍历:假设从图中的某个顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后再访问此邻接点的未被访问的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有未被访问的,则另选未被访问的反复以上环节,是一个非递归过程。d.图的深度优先遍历:假设从图中某顶点v出发,依依次访问v的邻接顶点,然后再继续访问这个邻接点的系一个邻接点,如此反复,直至所有的点都被访问,这是个递归的过程。e.图的连通分量:这是对一个非强连通图的遍历,从多个结点出发进行搜索,而每一次从一个新的起始点出发进行搜索过程中得到的顶点访问序列恰为其连通分量的顶点集。本程序运用的图的深度优先遍历算法。2.数据结构设计:ADTQueue{数据对象:D={ai|ai∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=1,2,3,……,n}基本操作:InitQueue(&Q)操作结果:构造一个空队列Q。QueueEmpty(Q)初始条件:Q为非空队列。操作结果:若Q为空队列,则返回真,否则为假。EnQueue(&Q,e)初始条件:Q为非空队列。操作结果:插入元素e为Q的新的队尾元素。DeQueue(&Q,e)初始条件:Q为非空队列。操作结果:删除Q的队头元素,并用e返回其值。}ADTQueueADTGraph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。数据关系R:R={VR}VR={<v,w>|v,w∈V且P(v,w),<v,w>表达从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P:CreatGraph(&G,V,VR);初始条件:V是图的顶点集,VR是图中弧的集合。操作结果:按V和VR的定义构造图G。BFSTraverse(G,visit());初始条件:图G存在,Visit是定点的应用函数。操作结果:对图进行广度优先遍历。在遍历过程中对每个顶点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败。DFSTraverse(G,visit());初始条件:图G存在,Visit是定点的应用函数。操作结果:对图进行广度优先遍历。在遍历过程中对每个顶点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败。DFStra_fen(G)初始条件:图G存在,存在图的深度优先遍历算法。操作结果:从多个顶点对图进行深度优先遍历,得到连通分量。}ADTGraph;软件结构设计:函数名返回值类型creatMGraph_L(G)intcreatadj(gra,G)intljjzprint(G)voidadjprint(gra,G)voidBFSTraverse(gra)voidDFStra(gra)intDFSTraverse_fen(gra)intMiniSpanTree_PRIM(g,G.vexnum)intMiniSpanTREE_KRUSCAL(G,gra)void三、具体设计定义程序中所有用到的数据及其数据结构,及其基本操作的实现;邻接矩阵定义:typedefstructArcCell{ VRTypeadj;//VRType是顶点关系类型。对无权图,用1或0表达相邻否;对带权图,则为权值类型 InfoType*info;//该弧相关信息的指针}ArcCell,AdjMatrix[max][max];typedefstruct{ VertexTypevexs[max];//顶点向量 AdjMatrixarcs;//邻接矩阵 intvexnum,arcnum;//图的当前顶点数和弧数}MGraph_L;邻接表的定义:typedefstructArcNode//弧结点{ intadjvex;//该弧指向的顶点的位置 structArcNode*nextarc;//指向下一条弧的指针 InfoType*info;//该弧相关信息的指针}ArcNode;typedefstructVNode//邻接链表顶点头接点{ VertexTypedata;//顶点信息 ArcNode*firstarc;//指向第一条依附该顶点的弧的指针}VNode,AdjList;typedefstruct//图的定义{ AdjListvertices[max]; intvexnum,arcnum;//图的当前顶点数和弧数}ALGraph;队列定义:typedefstructQNode{ QElemTypedata; structQNode*next;}QNode,*QueuePtr;typedefstruct{ QueuePtrfront;//队头指针 QueuePtrrear;//队尾指针}LinkQueue;主函数和其他函数的伪码算法;主函数:intmain(){ ints; chary='y';cout<<"||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤菜单¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||"<<endl;cout<<"||-------------------------【0、创建一个无向图------------------------------||"<<endl;cout<<"||-------------------------【1、显示该图的邻接矩阵--------------------------||"<<endl;cout<<"||-------------------------【2、显示该图的邻接表----------------------------||"<<endl; cout<<"||-------------------------【3、广度优先遍历--------------------------------||"<<endl;cout<<"||-------------------------【4、深度优先遍历--------------------------------||"<<endl;cout<<"||-------------------------【5、最小生成树MiniSpanTree_PRIM算法-------------||"<<endl;cout<<"||-------------------------【6、最小生成树MiniSpanTree_KRUSCAL算法----------||"<<endl;cout<<"||-------------------------【7、连通分量------------------------------------||"<<endl; cout<<"||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||"<<endl; while(y=='y') { cout<<"请选择菜单:"<<endl;cin>>s; if(s==0) { ++o; if(o==2) { n=0; l=0; o=0; } } switch(s) { case0:cout<<"创建一个无向图:"<<endl; MGraph_LG; creatMGraph_L(G); ALGraphgra; creatadj(gra,G);break; case1:cout<<"邻接矩阵显示如下:"<<endl; ljjzprint(G);break;case2:cout<<"邻接表显示如下:"<<endl;adjprint(gra,G);break;case3:cout<<"广度优先遍历:";BFSTraverse(gra);cout<<endl;break;case4: cout<<"深度优先遍历:";DFStra(gra);cout<<endl;break;case5: if(n==0){cout<<"无权图没有最小生成树";break;} elseif(l>0){cout<<"若该图为非强连通图(具有多个连通分量)时,最小生成树不存在"<<endl;break;} else { inti,g[max][max]; for(i=0;i!=G.vexnum;++i) for(intj=0;j!=G.vexnum;++j) g[i+1][j+1]=G.arcs[i][j].adj; cout<<"普利姆算法:"<<endl; MiniSpanTree_PRIM(g,G.vexnum); break; }case6:if(n==0){cout<<"无权图没有最小生成树";break;} elseif(l>0){cout<<"该图为非强连通图(具有多个连通分量),最小生成树不存在"<<endl;break;} else { cout<<"克鲁斯卡尔算法:"<<endl;MiniSpanTREE_KRUSCAL(G,gra);break; }case7:cout<<"连通分量:"<<endl; DFSTraverse_fen(gra);break; } cout<<endl<<"是否继续?y/n:";cin>>y;if(y=='n')break; } return0;}邻接矩阵存储:intcreatMGraph_L(MGraph_L&G)//创建图用邻接矩阵表达{ charv1,v2; inti,j,w; cout<<"请输入顶点和弧的个数"<<endl; cin>>G.vexnum>>G.arcnum; cout<<"输入各个顶点"<<endl; for(i=0;i<G.vexnum;++i) { cin>>G.vexs[i]; } for(i=0;i<G.vexnum;++i) for(j=0;j<G.vexnum;++j) { G.arcs[i][j].adj=int_max; G.arcs[i][j].info=NULL; } for(intk=0;k<G.arcnum;++k) { cout<<"输入一条边依附的顶点和权"<<endl; cin>>v1>>v2>>w;//输入一条边依附的两点及权值 i=localvex(G,v1);//拟定顶点V1和V2在图中的位置 j=localvex(G,v2); G.arcs[i][j].adj=w; G.arcs[j][i].adj=w; } for(i=0;i!=G.vexnum;++i) for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj!=1&&G.arcs[i][j].adj<int_max)n+=1; } if(n>=1)cout<<"这是一个有权图"<<endl; elsecout<<"这是一个无权图"<<endl; cout<<"图G邻接矩阵创建成功!"<<endl; returnG.vexnum;}邻接矩阵的输出:voidljjzprint(MGraph_LG)//邻接矩阵的输出{ inti,j; if(n==0) { for(i=0;i!=G.vexnum;++i) { for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj==int_max){cout<<"0"<<"";} else{cout<<G.arcs[i][j].adj<<"";} } cout<<endl; } } else { for(i=0;i!=G.vexnum;++i) { for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj==int_max){cout<<"∞"<<"";} else{cout<<G.arcs[i][j].adj<<"";} } cout<<endl; } }}用邻接表存储图:intcreatadj(ALGraph&gra,MGraph_LG)//用邻接表存储图{ inti=0,j=0; ArcNode*arc;//,*tem,*p; for(i=0;i!=G.vexnum;++i) { gra.vertices[i].data=G.vexs[i]; gra.vertices[i].firstarc=NULL; } for(i=0;i!=G.vexnum;++i) for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj!=int_max) { arc=(ArcNode*)malloc(sizeof(ArcNode)); arc->adjvex=j; arc->nextarc=gra.vertices[i].firstarc; gra.vertices[i].firstarc=arc; } } gra.vexnum=G.vexnum; gra.arcnum=G.arcnum; cout<<"图G邻接表创建成功!"<<endl; return1;}邻接表输出:voidadjprint(ALGraphgra,MGraph_LG)//邻接表输出{ inti; for(i=0;i!=gra.vexnum;++i) { ArcNode*p; cout<<"["<<i<<","<<G.vexs[i]<<"]"; p=gra.vertices[i].firstarc; while(p!=NULL) { cout<<"->"<<"["<<p->adjvex<<"]"; p=p->nextarc; } cout<<"->"<<"End"; cout<<endl; }}初始化队列:StatusInitQueue(LinkQueue&Q)//初始化队列{ Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q.front)return0;//存储分派失败 Q.front->next=NULL; return1;}入队:StatusEnQueue(LinkQueue&Q,QElemTypee)//入队,插入元素e为Q的新的队尾元素{ QueuePtrp; p=(QueuePtr)malloc(sizeof(QNode)); if(!p)return0;//存储分派失败 p->data=e;p->next=NULL; Q.rear->next=p;Q.rear=p; return1;}出队:StatusDeQueue(LinkQueue&Q,QElemType&e)//出队,若队列不空,则删除Q的队头元素,用e返回,并返回真,否则假{ QueuePtrp; if(Q.front==Q.rear)return0; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p)Q.rear=Q.front; free(p); return1;}判断队为空:StatusQueueEmpty(LinkQueueQ)//判断队为空{ if(Q.front==Q.rear)return1; return0;}广度优先遍历:voidBFSTraverse(ALGraphgra){ inti,e; LinkQueueq; for(i=0;i!=gra.vexnum;++i)visited[i]=0; InitQueue(q); for(i=0;i!=gra.vexnum;++i) if(!visited[i]) { visited[i]=1; cout<<gra.vertices[i].data; EnQueue(q,i); while(!QueueEmpty(q)) { DeQueue(q,e); for(we=firstadjvex(gra,gra.vertices[e]);we>=0;we=nextadjvex(gra,gra.vertices[e],we)) { if(!visited[we]) { visited[we]=1; cout<<gra.vertices[we].data; EnQueue(q,we); } } } }}深度优先遍历:intDFS(ALGraphgra,inti){ visited[i]=1; intwe1; cout<<gra.vertices[i].data; for(we=firstadjvex(gra,gra.vertices[i]);we>=0;we=nextadjvex(gra,gra.vertices[i],we)) { we1=we; if(visited[we]==0) DFS(gra,we); we=we1; } return1;}intDFStra(ALGraphgra){ inti,j; for(i=0;i!=gra.vexnum;++i) { visited[i]=0; } for(j=0;j!=gra.vexnum;++j) { if(visited[j]==0)DFS(gra,j); } return0;}连通分量:intDFSTraverse_fen(ALGraphgra){ inti,j; for(i=0;i!=gra.vexnum;++i) visited[i]=0; for(j=0;j!=gra.vexnum;++j) { if(visited[j]==0) { DFS(gra,j); cout<<endl; l++; } } return0;}重要函数的程序流程图,实现设计中主程序和其他子模块的算法,以流程图的形式表达。图的广度优先遍历图的邻接矩阵存储图的邻接表存储图的广度优先遍历图的邻接矩阵存储图的邻接表存储图的普利姆算法求最小生成树图的普利姆算法求最小生成树调试分析实际完毕的情况说明;a.先任意创建一个图;b.图的DFS,BFS的递归和非递归算法的实现c.最小生成树(两个算法)的实现,求连通分量的实现d.规定用邻接矩阵、邻接表等多种结构存储实现支持的数据类型:整型和字符型2.程序的性能分析,涉及时空分析;本程序的图的遍历是以邻接表做图的存储结构,其时间复杂度为O(n+e)。3.上机过程中出现的问题及其解决方案;a.程序开始对无权图和有权图的邻接矩阵的输出时,无边都用的10000(无穷大int_max)表达的,这种表达和我们习惯上的0与∞的表达有差异。所以在程序中定义了全局变量n(初值为0),来判断创建的无向图是有权图还是无权图,n>0为有权图,此时输出的时候用∞代替10000;n=0为无权图,此时输出的时候用0代替10000.b.程序中有的功能对某些图是不合用的,比如无权图没有最小生成树,非强连通图没有最小生成树等。所以在程序中又新增了全局变量l,l>0时表达为非强连通图,则在求最小生成树时报错。C.当程序先创建一个有权图后,n的值会大于1,第二次创无权图时也会被程序认为有权图,所以在程序中在定义全局变量o(初值为0),来判断创建了几次图,当第二次创建图,即o=2时,所有全局变量在开始全归零。程序中可以改善的地方说明;当建立一个图时先得求其连通分量,从而拟定全局变量l的值,从而才干判断该图是否有最小生成树。测试结果创建一个无权图:创建一个费强连通的有权图:创建一个有权连通图:用户手册a.先选0创建一个图。b.选择y继续操作。c.按照菜单编码选择操作。七、体会与自我评价在做这个程序的时候你一方面必须知道图的一些概念,图是一种较线性表和树更为复杂的数据结构。在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素也许和下一层中多个元素(及其孩子结点)相关但只能和上一层中一个元素(即双亲结点)相关;而在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都也许相关。当我们拿到一个图时,我们对该图的遍历就要有一些方法,所以有了深度优先遍历和广度优先遍历,我们要明白这两种遍历是怎么实现的,然后根据我们人脑中的方法把它写成电脑算法。对一个图我们还定义了连通分量,所以将图存到电脑中时,我们对连通分量得有个算法。求图的最小生成树有两种算法,普利姆是从结点出发寻找权最小的边,知道所有结点都练通了;而克鲁斯卡尔算法则是从边出发,寻找使图连通的权值最小边的方法。算法的实现从人脑到电脑的转变是比较复杂的一件事,规定做到具体到实现该方法的每一个环节,然后再将每一个环节通过代码实现。这规定我们要明确各个数据元素和个元素之间的关系,然后才干明确使用算法去调用这些数据。通过本次的课程设计,我对数据结构有了一定的结识,明白了数据结构中数据,数据关系,及对其操作的方法。但同时也发现在自己有很多的局限性,在使用语言和如何精炼语言需要进行更多的训练。源代码:#include<iostream>#include<malloc.h>usingnamespacestd;#defineint_max10000//最大值staticintn=0;//全局变量,判断有权图和无权图staticinto=0;//全局变量,清除BUGstaticintl=0;//全局变量,清除BUG#defineinf9999//最小值的最大值#definemax20//最大顶点个数typedefintVRType,QElemType,Status;typedefcharInfoType,VertexType;//|||||||||||||||||||||||||邻接矩阵|||||||||||||||||||||||||||||||//----------------------------邻接矩阵定义-------------------------typedefstructArcCell{ VRTypeadj;//VRType是顶点关系类型。对无权图,用1或0表达相邻否;对带权图,则为权值类型 InfoType*info;//该弧相关信息的指针}ArcCell,AdjMatrix[max][max];typedefstruct{ VertexTypevexs[max];//顶点向量 AdjMatrixarcs;//邻接矩阵 intvexnum,arcnum;//图的当前顶点数和弧数}MGraph_L;//-----------------------------------------------------------------intlocalvex(MGraph_LG,charv)//返回V的位置{ inti=0; while(G.vexs[i]!=v)++i; returni;}intcreatMGraph_L(MGraph_L&G)//创建图用邻接矩阵表达{ charv1,v2; inti,j,w; cout<<"请输入顶点和弧的个数"<<endl; cin>>G.vexnum>>G.arcnum; cout<<"输入各个顶点"<<endl; for(i=0;i<G.vexnum;++i) { cin>>G.vexs[i]; } for(i=0;i<G.vexnum;++i) for(j=0;j<G.vexnum;++j) { G.arcs[i][j].adj=int_max; G.arcs[i][j].info=NULL; } for(intk=0;k<G.arcnum;++k) { cout<<"输入一条边依附的顶点和权"<<endl; cin>>v1>>v2>>w;//输入一条边依附的两点及权值 i=localvex(G,v1);//拟定顶点V1和V2在图中的位置 j=localvex(G,v2); G.arcs[i][j].adj=w; G.arcs[j][i].adj=w; } for(i=0;i!=G.vexnum;++i) for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj!=1&&G.arcs[i][j].adj<int_max)n+=1; } if(n>=1)cout<<"这是一个有权图"<<endl; elsecout<<"这是一个无权图"<<endl; cout<<"图G邻接矩阵创建成功!"<<endl; returnG.vexnum;}voidljjzprint(MGraph_LG)//邻接矩阵的输出{ inti,j; if(n==0) { for(i=0;i!=G.vexnum;++i) { for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj==int_max){cout<<"0"<<"";} else{cout<<G.arcs[i][j].adj<<"";} } cout<<endl; } } else { for(i=0;i!=G.vexnum;++i) { for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj==int_max){cout<<"∞"<<"";} else{cout<<G.arcs[i][j].adj<<"";} } cout<<endl; } }}//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||//-------------------------邻接表的定义-----------------------typedefstructArcNode//弧结点{ intadjvex;//该弧指向的顶点的位置 structArcNode*nextarc;//指向下一条弧的指针 InfoType*info;//该弧相关信息的指针}ArcNode;typedefstructVNode//邻接链表顶点头接点{ VertexTypedata;//顶点信息 ArcNode*firstarc;//指向第一条依附该顶点的弧的指针}VNode,AdjList;typedefstruct//图的定义{ AdjListvertices[max]; intvexnum,arcnum;//图的当前顶点数和弧数}ALGraph;intcreatadj(ALGraph&gra,MGraph_LG)//用邻接表存储图{ inti=0,j=0; ArcNode*arc; for(i=0;i!=G.vexnum;++i) { gra.vertices[i].data=G.vexs[i]; gra.vertices[i].firstarc=NULL; } for(i=0;i!=G.vexnum;++i) for(j=0;j!=G.vexnum;++j) { if(G.arcs[i][j].adj!=int_max) { arc=(ArcNode*)malloc(sizeof(ArcNode)); arc->adjvex=j; arc->nextarc=gra.vertices[i].firstarc; gra.vertices[i].firstarc=arc; } } gra.vexnum=G.vexnum; gra.arcnum=G.arcnum; cout<<"图G邻接表创建成功!"<<endl; return1;}voidadjprint(ALGraphgra,MGraph_LG)//邻接表输出{ inti; for(i=0;i!=gra.vexnum;++i) { ArcNode*p; cout<<"["<<i<<","<<G.vexs[i]<<"]"; p=gra.vertices[i].firstarc; while(p!=NULL) { cout<<"->"<<"["<<p->adjvex<<"]"; p=p->nextarc; } cout<<"->"<<"End"; cout<<endl; }}//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||//------------------------队列定义------------------------typedefstructQNode{ QElemTypedata; structQNode*next;}QNode,*QueuePtr;typedefstruct{ QueuePtrfront;//队头指针 QueuePtrrear;//队尾指针}LinkQueue;//---------------------------------------------------------StatusInitQueue(LinkQueue&Q)//初始化队列{ Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q.front)return0;//存储分派失败 Q.front->next=NULL; return1;}StatusEnQueue(LinkQueue&Q,QElemTypee)//入队,插入元素e为Q的新的队尾元素{ QueuePtrp; p=(QueuePtr)malloc(sizeof(QNode)); if(!p)return0;//存储分派失败 p->data=e;p->next=NULL; Q.rear->next=p;Q.rear=p; return1;}StatusDeQueue(LinkQueue&Q,QElemType&e)//出队,若队列不空,则删除Q的队头元素,用e返回,并返回真,否则假{ QueuePtrp; if(Q.front==Q.rear)return0; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p)Q.rear=Q.front; free(p); return1;}StatusQueueEmpty(LinkQueueQ)//判断队为空{ if(Q.front==Q.rear)return1; return0;}//----------------------------图的遍历----------------------------intvisited[max];//访问标记intwe;intfirstadjvex(ALGraphgra,VNodev)//返回依附顶点V的第一个点//即以V为尾的第一个结点{ if(v.firstarc!=NULL)returnv.firstarc->adjvex;}intnextadjvex(ALGraphgra,VNodev,intw)//返回依附顶点V的相对于W的下一个顶点{ ArcNode*p; p=v.firstarc; while(p!=NULL&&p->adjvex!=w) { p=p->nextarc; } if(p->adjvex==w&&p->nextarc!=NULL) { p=p->nextarc; returnp->adjvex; } if(p->adjvex==w&&p->nextarc==NULL) return-10;}//----------------------------广度优先遍历----------------------------voidBFSTraverse(ALGraphgra){ inti,e; LinkQueueq; for(i=0;i!=gra.vexnum;++i)visited[i]=0; InitQueue(q); for(i=0;i!=gra.vexnum;++i) if(!visited[i]) { visited[i]=1; cout<<gra.vertices[i].data; EnQueue(q,i); while(!QueueEmpty(q)) { DeQueue(q,e); for(we=firstadjvex(gra,gra.vertices[e]);we>=0;we=nextadjvex(gra,gra.vertices[e],we)) { if(!visited[we]) { visited[we]=1; cout<<gra.vertices[we].data; EnQueue(q,we); } } } }}//---------------------------------深度优先遍历--------------------------------intDFS(ALGraphgra,inti){ visited[i]=1; intwe1; cout<<gra.vertices[i].data; for(we=firstadjvex(gra,gra.vertices[i]);we>=0;we=nextadjvex(gra,gra.vertices[i],we)) { we1=we; if(visited[we]==0) DFS(gra,we); we=we1; } return1;}intDFStra(ALGraphgra){ inti,j; for(i=0;i!=gra.vexnum;++i) { visited[i]=0; } for(j=0;j!=gra.vexnum;++j) { if(visited[j]==0)DFS(gra,j); } return0;}//----------------------------求连通分量------------------------------intDFSTraverse_fen(ALGraphgra){ inti,j; for(i=0;i!=gra.vexnum;++i) visited[i]=0; for(j=0;j!=gra.vexnum;++j) { if(visited[j]==0) { DFS(gra,j); cout<<endl; l++; } } return0;}//-----------------------------最小生成树的普利姆算法-----------------------------typedefstruct{ intadjvex; intlowcost;}closedge;intMiniSpanTree_PRIM(intg[][max],intn){ intlowcost[max],prevex[max];//lowcost[]存储当前集合分别到剩余结点的最小权值//prevex[]存储最短途径的前一个结点 inti,j,k,min; for(i=2;i<=n;i++)//n个顶点,n-1条边 { lowcost[i]=g[1][i];//初始化 prevex[i]=1;//顶点未加入到最小生成树中 } lowcost[1]=0;//标志顶点1加入U集合 for(i=2;i<=n;i++)//形成n-1条边的生成树 { min=inf; k=0; for(j=2;j<=n;j++)//寻找满足边的一个顶点在U,另一个顶点在V的最小边 if((lowcost[j]<min)&&(lowcost[j]!=0)) { min=lowcost[j]; k=j; } cout<<"("<<prevex[k]-1<<","<<k-1<<")"<<min; lowcost[k]=0;//顶点k加入U for(j=2;j<=n;j++)//修改由顶点k到其他顶点边的权值 if(g[k][j]<lowcost[j]) { lowcost[j]=g[k][j]; prevex[j]=k; } cout<<endl; } return0;}//-------------------------最小生成树的克鲁斯卡尔算法---------------------------intacrvisited[max];//克鲁斯卡尔弧标记数组intfind(intacrvisited[],intf){ while(acrvisited[f]>0)f=acrvisited[f]; returnf;}typedefstructacr{ intpre;//弧的一结点 intbak;//弧另一结点 intweight;//弧的权}edg;voidMiniSpanTREE_KRUSCAL(MGraph_LG,ALGraphgra){ edgedgs[max]; inti,j,k=0; for(i=0;i!=G.vexnum;++i) for(j=i;j!=G.vexnum;++j) { if(G.arcs[i][j].adj!=int_max) { edgs[k].pre=i; edgs[k].bak=j; edgs[k].weight=G.arcs[i][j].adj; ++k; } } intx,y,m,n; intbuf,edf; for(i=0;i!=gra.arcnum;++i) acrvisited[i]=0; for(j=0;j!=G.arcnum;++j) { m=int_max; for(i=0;i!=G.arcnum;++i) { if(edgs[i].weight<m) { m=edgs[i].weight; x=edgs[i].pre; y=edgs[i].bak; n=i; } } buf=find(acrvisited,x); edf=find(acrvisited,y); edgs[n].weight=int_max; if(buf!=edf) { acrvisited[buf]=edf; cout<<"("<<x<<","<<y<<")"<<m; cout<<endl; } }}intmain(){ ints; chary='y';cout<<"||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤菜单¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||"<<endl;cout<<"||-------------------------【0、创建一个无向图------------------------------||"<<endl;cout<<"||-------------------------【1、显示该图的邻

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论