ImageVerifierCode 换一换
格式:DOCX , 页数:31 ,大小:96.69KB ,
资源ID:4226779      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4226779.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(图的基本操作与实现.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

图的基本操作与实现.docx

1、图的基本操作与实现摘要: 图(Graph)是一种非线性结构,它的每一个顶点可以与多个其它顶点相关联,各顶点之间的关系是任意的。这种结构的灵活性很强,可以用来描述和求解更多的实际问题,因此得到广泛的应用。最典型的应用领域有电路分析、寻找最短路线、项目规划、鉴别化合物、统计力学、遗传学、控制论、语言学,以及一些社会科学中。反过来,也正是由于其限制很少,已不再属于线性结构,因此运用这类结构时需要有更多的技巧。本课题是在VC+环境下,运用图的性质完成各种基本操作的实现。关键词:邻接矩阵;邻接表;深度(广度)优先遍历;连通分量;递归1需求分析1.1课程设计题目(1)自选存储结构,输入含n个顶点(用字符表

2、示顶点)和e条边的图G;(2)求每个顶点的度,输出结果;(3)指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列(提示:使用一个栈实现DFS);(4)指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列(提示:使用一个队列实现BFS);(5)输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关连的边,并作DFS遍历(执行操作3);否则输出信息“无x”;(6)判断图G是否是连通图,输出信息“YES”/“NO”;(7)如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G,然再执行操作(2);反之亦然。1.2课程设计任务及要求1.搜集图方面

3、的资料; 2.负责设计数据结构,画好流程图,编写代码; 3.撰写课程设计报告; 4.参加答辩。1.3课程设计思想1.3.1 图的邻接表表示在第i行的单链表中,各结点分别存放与同一个顶点vi关联的各条边。各结点配有标识dest,指示该边的另一个顶点;还配有指针link,指向同一链表中的下一条边的边结点。对于带权图,结点中还要保存该边的权值cost。通过在顶点表的第i个顶点信息中保存的指针adj,可以找到与顶点i对应的边链表的第一个边结点;此外,该记录还保存有该顶点的其他信息。1.3.2 图的深度优先搜索 深度优先搜索是个不断探查和回溯的过程。在探查的每一步,算法都有一个当前顶点。最初的当前顶点,

4、也就是指定的起始顶点。每一步探查过程中,首先对当前顶点v进行访问,并立即设置该顶点的访问标志visitedv=true。接着在v的所有邻接顶点中,找出尚未访问过的一个,将其作为下一步探查的当前顶点。倘若当前顶点的所有邻接顶点都已经被访问过,则退回一步,将前一步所访问的顶点重新取出,当作探查的当前顶点。重复上述过程,直到最初指定起始顶点的所有邻接顶点都被访问到,此时连通图中的所有顶点也必然都被访问过了。1.3.3 图的广度优先搜索广度优先搜索时一个逐层遍历的过程,在此过程中,图中有多少顶点就要重复多少步。每一步都有一个当前顶点。最初的当前顶点是主过程指定的起始顶点。在每一步中,首先访问当前顶点v

5、,并设置该顶点的访问标志visitedv=true。接着依次访问v的各个未曾被访问过的邻接顶点w1,w2,wt,然后再顺序访问w1,w2,wt的所有还未被访问过的邻接顶点。再从这些访问过的顶点出发,再访问它们的所有还未被访问过的邻接顶点,如此做下去,直到图中所有顶点都被访问为止。2概要设计2.1程序的整体功能结构输入1个图先求出每个顶点的度,输出结果;然后指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列;接着指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列;其次输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关连的边,并作DFS遍历(执行操作3);否

6、则输出信息“无x”;下一步是判断图G是否是连通图,输出信息“YES”/“NO”;最后如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G,然再执行操作(2);反之亦然 。2.2数据结构的设计2.2.1边节点类的定义struct Edge /边结点的定义 int dest; /边的另一顶点位置 E cost; /边上的权值 Edge *link; /下一条边链指针;2.2.2顶点类的定义template /顶点的定义struct Vertex T data; /顶点的名字 Edge *adj; /边链表的头指针;2.2.3图类的定义template class Graph

7、 /图的类定义 protected: int maxVertices;/图中最大的顶点数 int numEdges; /当前边数 int numVertices; /当前顶点数 T *output; /存放遍历的数组 T *input; /存放输入数组 Vertex *NodeTable;/顶点表 (各边链表的头结点) int getVertexPos (const T vertx)/ 取顶点v在数组中的位置 int j=-1; for(int i=0;inumVertices;i+) if(NodeTablei.data=vertx) j=i; return j; void DFS(Grap

8、h& G, int v, bool visited) /图的深度优先搜索 coutG.getValue(v)=0 & inumVertices)?NodeTablei.data:0; bool insertVertex(const T &vertex); /插入顶点vertex bool insertEdge (int v1, int v2, E cost); /插入边(v1, v2),权值为cost bool removeVertex(int v); /删除指定的顶点 bool removeEdge(int v1,int v2); /删除一条边 int getFirstNeighbor (i

9、nt v);/取顶点 v 的第一个邻接顶点 int getNextNeighbor (int v, int w); /取 v 的邻接顶点 w 的下一邻接顶点 int getFirstCost (int v);/取顶点 v 的第一个邻接顶点的cost值 int getNextCost (int v, int w); /取 v 的邻接顶点 w 的下一邻接顶点的cost值void DFS(Graph& G,const T& v);/从顶点v出发对图G进行深度优先遍历的主过程 int BFS(Graph& G, const T& v); /图的广度优先搜索 void WheCan(Graph& G);

10、/判断是否为连通图 void OutPut();/输出 void HaveEdge(Graph& G);/求顶点的度 void SerachVertex(Graph& G);/输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关连的边,并作DFS遍历 void ChangeGraph(Graph& G); /将用邻接表表示的数转换为邻接矩阵表示 void Input();/输入;3详细设计和实现3.1算法流程图程序主要设计了六个功能:首先是求每个顶点的度,然后可以选择对图G作DFS(或BFS)搜索,接着可以判断此图是否连通,接着可以将图G转换为临街矩阵存储方式退出,最后可以对图G作查

11、找顶点。主函数流程如下:图3.1.1主函数流程图3.2 各个要求的实现方法3.2.1自选存储结构,输入含n个顶点(用字符表示顶点)和e 条边的图G 采用邻接表的存储结构N个顶点的输入存储到顶点节点链表( Vertex )中如果第n个节点和第m个节点之间含有一条边e,就将n和m的顶点链表中指向的边链表中存储入n和m在顶点表中的下标和权值3.2.2求每个顶点的度,输出结果顶点的度指与该顶点相关联的边的条数在用邻接链表做为图的存储方式中,要求一个顶点n的度只要去搜索存放顶点 n的边节点链表,其中存放了多少条边的信息,这个顶点的度就为多少。3.2.3指定任意顶点x为初始顶点,对图G作DFS遍历,输出D

12、FS顶点序列 DFS遍历指的是深度优先搜索深度优先搜索的基本思想:DFS 在访问图中某一起始顶点 v 后, 由 v 出发, 访问它的任一邻接顶点 w1; 再从 w1 出发, 访问与 w1邻 接但还没有访问过的顶点 w2; 然后再从 w2 出发, 进行类似的访问, 如此进行下去, 直至到达所有的邻接顶点都被访问过的顶点 u 为止。接着, 退回一步, 退到前一次刚访问过的顶点, 看是否还有其它没有被访问的邻接顶点。如果有, 则访问此顶点, 之后再从此顶点出发, 进行与前述类似的访问; 如果没有, 就再退回一步进行搜索。重复上述过程, 直到连通图中所有顶点都被访问过为止。3.2.4指定任意顶点x为初

13、始顶点,对图G作BFS遍历,输出BFS顶点序列 BFS指的是广度优先搜索BFS基本思想:BFS在访问了起始顶点 v 之后, 由 v 出发, 依次访问 v 的各个未被访问过的邻接顶点 w1, w2, , wt, 然后再顺序访问 w1, w2, , wt 的所有还未被访问过的邻接顶点。再从这些访问过的顶点出发,再访问它们的所有还未被访问过的邻接顶点, 如此做下去,直到图中所有顶点都被访问到为止。广度优先搜索是一种分层的搜索过程, 每向前走一步可能访问一批顶点, 不像深度优先搜索那样有往回退的情况。因此, 广度优先搜索不是一个递归的过程。3.2.5输入顶点x,查找图G:若存在含x的顶点,则删除该结点

14、及与之相关连的边,并作DFS遍历(执行操作3);否则输出信息“无x”;输入顶点,在顶点表中所搜是否含有这个顶点,如果没有,就输出“无x”。如果含有,搜索存放顶点 n的边节点链表,找出其中存放的顶点 m,然后将这个顶点m链表中的存放n的那个节点删除,同时将n中存放m的节点删除。然后在顶点链表中存放顶点n的节点删除。3.2.6判断图G是否是连通图,输出信息“YES”/“NO”;对图做BFS遍历,如果遍历到的顶点数等于当前的顶点数的个数,这个图就是联通图,反之就不是连通图3.2.7如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G,然再执行操作(2);反之亦然我采用的是邻接

15、矩阵做为图的存储结构。将用邻接表存储的图转化为邻接矩阵的存储的基本思想是:(1)将图的顶点表中存放的顶点的信息都存放在一个顶点矩阵中(2)逐个搜索各个顶点 的边节点链表,如果含有节点,将邻接矩阵中对应二维数组的值赋值为cost的值。顶点的度为:统计第 i 行 (列) 不为0 的个数可得顶点i 的度。3.3主程序设计/Graph.h#include#include#includeQueue.husing namespace std;template struct Edge /边结点的定义 int dest; /边的另一顶点位置 E cost; /边上的权值 Edge *link; /下一条边链指

16、针 Edge() /构造函数 Edge(int num,E cost):dest(num),weight(cost),link(NULL) /构造函数 bool operator!=(Edge& R) const /判边等否 return dest != R.dest; ;template /顶点的定义struct Vertex T data; /顶点的名字 Edge *adj; /边链表的头指针;template class Graph /图的类定义 protected: int maxVertices;/图中最大的顶点数 int numEdges; /当前边数 int numVertice

17、s; /当前顶点数 T *output; /存放遍历的数组 T *input; /存放输入数组 Vertex *NodeTable;/顶点表 (各边链表的头结点) int getVertexPos (const T vertx)/ 取顶点v在数组中的位置 int j=-1; for(int i=0;inumVertices;i+) if(NodeTablei.data=vertx) j=i; return j; void DFS(Graph& G, int v, bool visited) /图的深度优先搜索 coutG.getValue(v)=0 & inumVertices)?NodeTa

18、blei.data:0; bool insertVertex(const T &vertex); /插入顶点vertex bool insertEdge (int v1, int v2, E cost); /插入边(v1, v2),权值为cost bool removeVertex(int v); /删除指定的顶点 bool removeEdge(int v1,int v2); /删除一条边 int getFirstNeighbor (int v);/取顶点 v 的第一个邻接顶点 int getNextNeighbor (int v, int w); /取 v 的邻接顶点 w 的下一邻接顶点

19、int getFirstCost (int v);/取顶点 v 的第一个邻接顶点的cost值 int getNextCost (int v, int w); /取 v 的邻接顶点 w 的下一邻接顶点的cost值 void DFS(Graph& G,const T& v);/从顶点v出发对图G进行深度优先遍历的主过程 int BFS(Graph& G, const T& v); /图的广度优先搜索 void WheCan(Graph& G);/判断是否为连通图 void OutPut();/输出 void HaveEdge(Graph& G);/求顶点的度 void SerachVertex(G

20、raph& G);/输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关连的边,并作DFS遍历 void ChangeGraph(Graph& G); /将用邻接表表示的数转换为邻接矩阵表示 void Input();/输入;#includetemplate Graph:Graph() /构造函数:建立一个空的邻接表 maxVertices=100; numVertices=0; numEdges=0; NodeTable = new VertexmaxVertices; /创建顶点表数组 if (NodeTable = NULL) cerr存储分配错!endl; exit(1);

21、for (int i=0;imaxVertices;i+) NodeTablei.adj = NULL; output=new TmaxVertices;template Graph:Graph()/析构函数:删除一个邻接表 for (int i=0;inumVertices;i+) Edge *p = NodeTablei.adj; while (p != NULL) NodeTablei.adj = p-link; delete p; p = NodeTablei.adj; deleteNodeTable; /删除顶点表数组template bool Graph:insertVertex(

22、const T &vertex) /插入顶点 if(numVertices=maxVertices) return false; NodeTablenumVertices.data=vertex; numVertices+; return true;templatebool Graph:insertEdge (int v1, int v2, E cost)/插入边(v1, v2),权值为cost if(v1=0&v1=0&v2=numVertices) Edge*q, *p=NodeTablev1.adj; /v1对应的边链表头z指针 while(p!=NULL&p-dest!=v2) /寻找

23、邻接顶点v2 p=p-link; if(p!=NULL) /找到此边 不插入 return false; p=new Edge; /否则 创建新节点 q=new Edge; p-dest=v2; p-cost=cost; p-link=NodeTablev1.adj;/链入v1的边链表 NodeTablev1.adj=p; q-dest=v1; q-cost=cost; q-link=NodeTablev2.adj;/链入v2的边链表 NodeTablev2.adj=q; numEdges+; return true; else cerr参数有误!请重新输入!endl; exit(1); re

24、turn false; templatebool Graph:removeVertex(int v) if(numVertices=1|v=numVertices) cerr参数有误,请重新输入!endl; exit(1); return false; /表空或顶点超出范围 Edge *p,*s,*t; int k; while(NodeTablev.adj!=NULL) p=NodeTablev.adj; k=p-dest; s=NodeTablek.adj; t=NULL; while(s!=NULL&s-dest!=v) t=s; s=s-link; if(s!=NULL) if(t=N

25、ULL) NodeTablek.adj=s-link; else t-link=s-link; delete s; NodeTablev.adj=p-link; delete p; numEdges-; numVertices-; NodeTablev.data=NodeTablenumVertices.data; p=NodeTablev.adj=NodeTablenumVertices.adj; while(p!=NULL) s=NodeTablep-dest.adj; while(s!=NULL) if(s-dest=numVertices) s-dest=v; break; else s=s-link; return true;templatebool Graph:removeEdge(int v1,int v2) if(v1!=-1&v2!=-1) Edge *p=NodeTablev1.adj,*q=NULL,*s=p; while(p!=NULL&p-des

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1