一,图的两种算法
本章承接上一章 具体的一些说明或者资料可以到上一章中寻找
1, 深度优先遍历
说深度优先遍历之前 我们先说说走迷宫的走法,
要探索迷宫中所有的通道,我们需要做以下几种事,
1):选择一条没有标记过的通道,在你走过的路上铺一条绳子;
2):标记所有你第一次路过的路口和通道;
3):当来到一个标记的路口(有绳子的路口)时回退到上一个路口
4):当回退到的路口已经没有可走的通道时继续回退。
这样绳子可以保证你总能找到一条出路,标记保证了你不会两次同时经历一条通道
代码如下
package com.lxy.datastructure.graph; public class DepthFirstSearch { private boolean[] marked;//是否被访问过 private int count;//与s联通的顶点 public DepthFirstSearch(Graph g,int s) { marked=new boolean[g.getV()]; dfs(g,s); } private void dfs(Graph g,int v){ marked[v]=true; count++; for(int w:g.adj(v)){ if(!marked(w))dfs(g, w); } } public boolean marked(int w){ return marked[w]; } public int count(){ return count; } }
2,广度优先遍历
1,取队列中的下一个顶点v并标记它
2,将与v相邻的所有未被标记的顶点加入;
重复以上步骤
代码如下
package com.lxy.datastructure.graph; import com.lxy.datastructure.queue.Queue; import com.lxy.datastructure.stack.Stack; public class BreadthFirstPaths { private boolean[] marked;//访问标记 private int[] edgeTo;// private int s;//起点 public BreadthFirstPaths(Graph g,int s){ this.s=s; marked=new boolean[g.getV()]; edgeTo=new int[g.getV()]; bfs(g,s); } private void bfs(Graph g,int v){ Queue<Integer> queue=new Queue<Integer>(); marked[v]=true; queue.push(v); while(!queue.isEmpty()){ int h=queue.pop(); for(int w:g.adj(h)){ if(!marked(w)){ queue.push(w); marked[w]=true; edgeTo[w]=h; } } } } public boolean marked(int v){ return marked[v]; } public boolean hasPathTo(int v){ return marked[v]; } public Iterable<Integer> pathTo(int v){ if(!hasPathTo(v)) return null; Stack<Integer> path=new Stack<Integer>(); for(int x=v;x!=s;x=edgeTo[x]){ path.push(x); } path.push(s); return path; } }
测试用例
package com.lxy.datastructure.graph; import java.io.File; import java.util.Arrays; import java.util.Iterator; import org.junit.Before; import org.junit.Test; import com.lxy.datastructure.queue.Queue; import edu.princeton.cs.introcs.In; import edu.princeton.cs.introcs.StdOut; public class GraphTest { String basePath=System.getProperty("user.dir"); File file1=null; File file2=null; Graph g1 =null; @Before public void setup(){ file1=new File(basePath,"data/graph/mediumG.txt"); file2=new File(basePath,"data/graph/tinyG.txt"); In in = new In(file2); g1=new Graph(in); } @Test public void testPrintGraph(){ System.out.println(g1.toString()); } /** * 深度优先遍历 */ @Test public void depthFirstPath(){ int s =0; DeptFirstPaths path=new DeptFirstPaths(g1, s); for (int v = 0; v < g1.getV(); v++) { if (path.hasPathTo(v)) { StdOut.printf("%d to %d: ", s, v); for (int x : path.pathTo(v)) { if (x == s) StdOut.print(x); else StdOut.print("-" + x); } StdOut.println(); } else { StdOut.printf("%d to %d: not connected\n", s, v); } } System.out.println(Arrays.toString(path.getEdgeTo())); for(Iterator<Integer> it=path.pathTo(6).iterator();it.hasNext();){ System.out.println(it.next()); } } /** * 广度优先遍历 */ @Test public void testBreadthFirstPath(){ int s =0; BreadthFirstPaths path=new BreadthFirstPaths(g1, s); for (int v = 0; v < g1.getV(); v++) { if (path.hasPathTo(v)) { StdOut.printf("%d to %d: ", s, v); for (int x : path.pathTo(v)) { if (x == s) StdOut.print(x); else StdOut.print("-" + x); } StdOut.println(); } else { StdOut.printf("%d to %d: not connected\n", s, v); } } } }
输出结果
广度优先遍历输出结果 0 to 0: 0 0 to 1: 0-1 0 to 2: 0-2 0 to 3: 0-5-3 0 to 4: 0-5-4 0 to 5: 0-5 0 to 6: 0-6 0 to 7: not connected 0 to 8: not connected 0 to 9: not connected 0 to 10: not connected 0 to 11: not connected 0 to 12: not connected 深度优先遍历输出结果 0 to 0: 0 0 to 1: 0-1 0 to 2: 0-2 0 to 3: 0-5-4-3 0 to 4: 0-5-4 0 to 5: 0-5 0 to 6: 0-5-4-6 0 to 7: not connected 0 to 8: not connected 0 to 9: not connected 0 to 10: not connected 0 to 11: not connected 0 to 12: not connected
相关推荐
邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历
图的深度遍历和广度遍历是两个重要的算法,这也是我们理解并掌握图这一数据结构的基础。通过此程序算法可以进一步掌握图的构造以及遍历的相关知识。 图的深度优先遍历算法 图的深度优先遍历(Depth-First Search,...
在本文中,我们将深入探讨图的数据结构以及如何对图进行深度优先遍历(DFS)和广度优先遍历(BFS)。首先,我们要理解图的基本概念。图是一种数据结构,用于表示对象之间的关系,其中的对象称为顶点或节点,而它们...
无向图建立、深度优先遍历和广度优先遍历实现算法 本文将详细介绍无向图的建立、深度优先遍历和广度优先遍历的实现算法。这些算法是数据结构中非常重要的内容,掌握它们对后续学习和应用非常重要。 一、无向图的...
广度优先遍历是一种遍历图的算法,先访问起始顶点v,然后由v出发访问v的各个未被访问过的邻接顶点w1,w2,...,wi,然后依次访问w1,w2,...,wi的所有未被访问过的邻接顶点,以此类推,直到遍历图中所有顶点为止。广度...
图的深度遍历和广度遍历是图论中的两种基本搜索策略,它们在计算机科学中有着广泛的应用,尤其是在算法设计、数据结构处理、网络路由等领域。本篇实验报告将详细探讨这两种遍历方法,并提供C语言实现的源代码。 ...
邻接矩阵表示法深度遍历和广度遍历 邻接矩阵表示法深度遍历和广度遍历 邻接矩阵表示法深度遍历和广度遍历 邻接矩阵表示法深度遍历和广度遍历
本文档详细介绍了数据结构中图的深度遍历和广度遍历算法的实现,包括图的基本操作、深度遍历算法和广度遍历算法的实现细节。这些算法在实际应用中具有重要的意义,可以用于解决许多实际问题。 知识点: * 图的基本...
广度优先搜索是一种从给定起点开始逐层遍历图中所有节点的算法,其主要思想类似于树的层次遍历。以下是BFS的主要步骤: 1. 初始化:所有节点标记为未访问,选择一个起始节点,将其标记为已访问。 2. 将起始节点入队...
数据结构很重要的一个部分,综合运用多种数据结构,有一定的综合性。
深度优先遍历通过尽可能深地遍历图的分支来访问尽可能多的节点,直到某个节点没有未被访问过的邻接点为止。广度优先遍历则先访问起始节点的所有邻近节点,然后再对每个邻近节点进行相同操作。 在数据结构中,图的...
在本主题中,我们重点关注的是图数据结构的深度优先遍历(DFS, Depth First Search)。 首先,数据结构是计算机程序设计的基础,常见的数据结构包括数组、链表、栈、队列、树和图等。每种数据结构都有其独特的特点...
根据给定文件的信息,我们可以总结出以下几个主要的知识点: ### 1. 图的定义与表示 ...以上就是关于图的建立及深度优先遍历和广度优先遍历的主要知识点。通过理解这些概念,可以帮助我们更好地分析和解决问题。
本项目关注的是图的遍历方法,特别是深度优先遍历(DFS)和广度优先遍历(BFS),这些都是图算法中的核心概念。 首先,我们要理解什么是邻接多重表。邻接多重表是一种图的表示方式,它为图的每个顶点创建一个链表,...
总结一下,C++实现的图的深度遍历和广度遍历是数据结构和算法学习的重要部分。理解并掌握这两种遍历方法有助于解决各种复杂的问题,如网络路由、拓扑排序、查找连通分量等。通过实践和理解这两个算法,你可以增强...
在这个主题中,我们将深入探讨图的深度遍历(Depth-First Search, DFS)和广度遍历(Breadth-First Search, BFS)这两种遍历算法,以及它们在数据结构基本实验中的应用。 **1. 图的基本概念** 图由顶点(Vertex)...
### 图的存储结构:邻接表 ...通过邻接表,不仅可以方便地实现图的创建,还可以有效地支持深度优先遍历和广度优先遍历等图算法的应用。理解并掌握这些基础知识对于深入学习计算机科学中的图论及其应用具有重要意义。
数据结构中的图是一种重要的抽象数据类型,用于表示实体之间的关系。在给定的题目中,主要涉及了图的两种遍历方法:深度优先遍历(DFS, Depth First Search)和广度优先遍历(BFS, Breadth First Search)。这两种...
数据结构实验报告主要关注的是图的遍历方法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。图是一种非线性的数据结构,由顶点和边组成,用于表示对象之间的关系。实验的目标是理解和掌握图的逻辑结构(如邻接矩阵...
本文主要讨论图的深度优先遍历和广度优先遍历的算法实现,包括获取图的所有边、输出邻接矩阵、图的深度遍历和广度优先遍历的实现。 获取图的所有边 在获取图的所有边时,我们需要定义 Edge 结构体来存储边的信息,...