




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
图的深度优先遍历和广度优先遍历 Java实现 收藏 一 图的基本概念及存储结构图G是由顶点的有穷集合,以及顶点之间的关系组成,顶点的集合记为V,顶点之间的关系构成边的集合EG=(V,E).说一条边从v1,连接到v2,那么有v1Ev2(E是V上的一个关系)=E.图有有向图,无向图之分,无向图的一条边相当于有向图的中两条边,即如果无向图的顶点v1和v2之间有一条边,那么既有从v1连接到v2的边,也有从v2连接到v1的边,E 并且E,而有向图是严格区分方向的。一般图的存储有两种方式1)相邻矩阵,用一个矩阵来保持边的情况,E则Matrixv1v2=Weight.2)邻接表,需要保存一个顺序存储的顶点表和每个顶点上的边的链接表。这里的实现采用第二种方案,另外图又复杂图,简单图之分,复杂图可能在两点之间同一个方向有多条边,我们考虑的都是无环简单图,无环简单图是指顶点没有自己指向自己的边的简单图,即任取vi属于V = 不属于E并且没有重复边。我们先给出图的ADT:package algorithms.graph;/* * The Graph ADT * author yovn * */public interface Graph /mark public static interface Edge public int getWeight(); int vertexesNum(); int edgeNum(); boolean isEdge(Edge edge); void setEdge(int from,int to, int weight); Edge firstEdge(int vertex); Edge nextEdge(Edge edge); int toVertex(Edge edge); int fromVertex(Edge edge); String getVertexLabel(int vertex); void assignLabels(String labels); void deepFirstTravel(GraphVisitor visitor); void breathFirstTravel(GraphVisitor visitor); 其中的方法大多数比较一目了然,其中1)Edge firstEdge(int vertex)返回指定节点的边的链表里存的第一条边2)Edge nextEdge(Edge edge),顺着边链表返回下一条边3)fromVertex,toVertex很简单返回该边的起始顶点和终结顶点4)getVertexLabel返回该定点对应的标号,assignLabels给所有顶点标上号GraphVisitor是一个很简单的接口:package algorithms.graph;/* * author yovn *- */public interface GraphVisitor void visit(Graph g,int vertex);OK,下面是该部分实现:package algorithms.graph;import java.util.Arrays;/* * author yovn * */public class DefaultGraph implements Graph private static class _Edge implements Edge private static final _Edge NullEdge=new _Edge(); int from; int to; int weight; _Edge nextEdge; private _Edge() weight=Integer.MAX_VALUE; _Edge(int from, int to, int weight) this.from=from; this.to=to; this.weight=weight; public int getWeight() return weight; private static class _EdgeStaticQueue _Edge first; _Edge last; private int numVertexes; private String labels; private int numEdges; private _EdgeStaticQueue edgeQueues; /tag the specified vertex be visited or not private boolean visitTags; /* * */ public DefaultGraph(int numVertexes) if(numVertexes1) throw new IllegalArgumentException(); this.numVertexes=numVertexes; this.visitTags=new booleannumVertexes; this.labels=new StringnumVertexes; for(int i=0;inumVertexes;i+) labelsi=i+; this.edgeQueues=new _EdgeStaticQueuenumVertexes; for(int i=0;i=numVertexes) throw new IllegalArgumentException(); return edgeQueuesvertex.first; /* (non-Javadoc) * see algorithms.graph.Graph#isEdge(algorithms.graph.Graph.Edge) */ Override public boolean isEdge(Edge edge) return (edge!=_Edge.NullEdge); /* (non-Javadoc) * see algorithms.graph.Graph#nextEdge(algorithms.graph.Graph.Edge) */ Override public Edge nextEdge(Edge edge) return (_Edge)edge).nextEdge; /* (non-Javadoc) * see algorithms.graph.Graph#vertexesNum() */ Override public int vertexesNum() return numVertexes; Override public int fromVertex(Edge edge) return (_Edge)edge).from; Override public void setEdge(int from, int to, int weight) /we dont allow ring exist if(from=numVertexes|to=numVertexes|weight0|from=to)throw new IllegalArgumentException(); _Edge edge=new _Edge(from,to,weight); edge.nextEdge=_Edge.NullEdge; if(edgeQueuesfrom.first=_Edge.NullEdge) edgeQueuesfrom.first=edge; else edgeQueuesfrom.last.nextEdge=edge; edgeQueuesfrom.last=edge; Override public int toVertex(Edge edge) return (_Edge)edge).to; Override public String getVertexLabel(int vertex) return labelsvertex; Override public void assignLabels(String labels) System.arraycopy(labels, 0, this.labels, 0, labels.length); /to be continue二 深度优先周游即从从某一点开始能继续往前就往前不能则回退到某一个还有边没访问的顶点,沿这条边看该边指向的点是否已访问,如果没有访问,那么从该指向的点继续操作。那么什么时候结束呢,这里我们在图的ADT实现里加上一个标志数组。该数组记录某一顶点是否已访问,如果找不到不到能继续往前访问的未访问点,则结束。你可能会问,如果指定图不是连通图(既有2个以上的连通分量)呢?OK,解决这个问题,我们可以让每一个顶点都有机会从它开始周游。下面看deepFirstTravel的实现: /* (non-Javadoc) * see algorithms.graph.Graph#deepFirstTravel(algorithms.graph.GraphVisitor) */ Override public void deepFirstTravel(GraphVisitor visitor) Arrays.fill(visitTags, false);/reset all visit tags for(int i=0;inumVertexes;i+) if(!visitTagsi)do_DFS(i,visitor); private final void do_DFS(int v, GraphVisitor visitor) /first visit this vertex visitor.visit(this, v); visitTagsv=true; /for each edge from this vertex, we do one time /and this for loop is very classical in all graph algorithms for(Edge e=firstEdge(v);isEdge(e);e=nextEdge(e) if(!visitTagstoVertex(e) do_DFS(toVertex(e),visitor); 三 广度优先周游广度优先周游从每个指定顶点开始,自顶向下一层一层的访问。上一层所有顶点访问完了才继续下一层的访问。可以把二叉树的广度优先周游看成图的广度优先周游的特例。(二叉树是连通的无回路的有向图,也是一棵根树)同样,广度优先也要借助与一个队列来存储待访问顶点下面是breathFirstTravel的实现,为了减小Java库的影响,我自己实现一个很简单的队列。(你也可以使用ArrayList,但是记住队列的定义,只能在头删除,在尾插入):private static class _IntQueue private static class _IntQueueNode _IntQueueNode next; int value; _IntQueueNode first; _IntQueueNode last; /queue can only insert to the tail void add(int i) _IntQueueNode node=new _IntQueueNode(); node.value=i; node.next=null; if(first=null)first=node; else last.next=node; last=node; boolean isEmpty() return first=null; /queue can only remove from the head int remove() int val=first.value; if(first=last) first=last=null; else first=first.next; return val; /* (non-Javadoc) * see algorithms.graph.Graph#breathFirstTravel(algorithms.graph.GraphVisitor) */ Override public void breathFirstTravel(GraphVisitor visitor) Arrays.fill(visitTags, false);/reset all visit tags for(int i=0;inumVertexes;i+) if(!visitTagsi) do_BFS(i,visitor); private void do_BFS(int v, GraphVisitor visitor) /and BFS will use an queue to keep the unvisited vertexes / we can also just use java.util.ArrayList _IntQueue queue=new _IntQueue(); queue.add(v); while(!queue.isEmpty() int fromV=queue.remove(); visitor.visit(this, fromV); visitTagsfromV=true; for(Edge e=firstEdge(fromV);isEdge(e);e=nextEdge(e) if(!visitTagstoVertex(e) queue.add(toVertex(e); OK,最后我们测试一下:/* * param args */ public static void main(String args) /* * For example, we have a graph: * 012 * * 3 4 5 * * 678 * * here ,all weight is 0, its a DAG(Dire
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 昆明运输协管员招聘面试题及答案
- 空乘岗位面试题库及答案
- 科研人员面试题库及答案
- 安全教育培训评价制度课件
- 安全教育培训记录总结课件
- 家电数码市场发展方向
- 希望以上标题符合您的要求
- 社交媒体推广协议的条款
- 农业产业化龙头企业农业产业链可持续发展战略与带动效应研究报告
- 安全教育培训能力不足课件
- 《鸿蒙应用开发项目教程》全套教学课件
- 2025年陕西省中考数学试题卷(含答案详解)
- 2025年注册计量师考试计量器具管理与维护试卷
- 国内公司外汇管理办法
- 高中数学教师学情分析现状的调查研究
- 起重作业安全知识考核试题(含答案)
- 第4课《古代诗歌四首》课件 2025-2026学年统编版语文七年级上册
- 肿瘤化疗静脉护理
- 灯笼鱼介绍课件
- 就业创业政策解读课件
- 2025至2030年中国特种设备检验检测行业市场发展调研及竞争格局预测报告
评论
0/150
提交评论