内容简介:图的遍历对于图这类题目来说非常重要,但是图的实现又非常的难。在这里我介绍下图的广度优先遍历和深度优先遍历,讲一下其中的算法思想。邻接矩阵表示:图的邻接矩阵存储结构定义如下:
图的遍历对于图这类题目来说非常重要,但是图的实现又非常的难。在这里我介绍下图的广度优先遍历和深度优先遍历,讲一下其中的算法思想。
1.图的存储结构
邻接矩阵表示:
图的邻接矩阵存储结构定义如下:
int n; boolean[][] a; Node(int n){ this.n=n; a = new boolean[n][n]; } void addEdge(int i, int j) { a[i][j] = true; } void removeEdge(int i, int j) { a[i][j] = false; } boolean hasEdge(int i, int j) { return a[i][j]; } 复制代码
邻接矩阵表示法的时间复杂度为O(n^2),空间复杂度也是O(n^2)。n代表图中顶点的个数。
邻接表表示:
图的邻接表存储结构定义如下:
//顶点的数量 private int V; //邻接表-数组类型的链表 private LinkedList<Integer> adj[]; //构造一个图 DepthFirstSearch(int v){ V = v; //数组链表 adj = new LinkedList[v]; for (int i = 0; i < v; i++) { adj[i]=new LinkedList(); } } //加入与顶点v相连的边v-w void addEdge(int v,int w){ adj[v].add(w); } 复制代码
时间复杂度为:O(V + E)其中V是图中顶点的数量,E是图中边的数量 。
还是看以前的书比较有亲和感!
2.广度优先遍历(Breadth-First-Search,BFS)
广度优先遍历类似与二叉树的层序遍历。它是一种分层的查找过程,每向前走一步能访问一批顶点,不像深度优先遍历那样有往回退的情况,因此它不是一个递归的算法。 为了实现逐层的访问,算法必须借助一个辅助队列,以记忆正在访问顶点的下一层顶点。
package com.zhoujian.solutions.dataStructure.graph; import java.util.*; /** * @author zhoujian123@hotmail.com 2018/4/26 10:28 * 图的广度优先遍历----借助队列 * 广度优先遍历类似于二叉树的层序遍历 * 图是用邻接表来存储(对于稀疏图来说,邻接表比较合适) * 时间复杂度:O(V+E),其中V是图中顶点的数量,E是图中边的数量 */ public class BreadthFirstSerch { private int V; //顶点 private LinkedList<Integer> adj[]; //领接表 //构造器,利用链表。v是顶点的个数 BreadthFirstSerch(int v){ V=v; adj = new LinkedList[v]; for (int i = 0; i <v; i++) { adj[i]=new LinkedList(); } } //加入一条边到图中 void addEdge(int v,int w){ adj[v].add(w); } //从给定的顶点开始遍历 void BFS(int s){ //默认将所有的顶点设置为未被访问(false) boolean visited[] = new boolean[V]; //创建一个队列 LinkedList<Integer> queue = new LinkedList<Integer>(); //把当前顶点设置为已访问并且入队 visited[s] = true; queue.add(s); while (queue.size()!=0){ //出队并打印出来 s=queue.poll(); System.out.println(s+""); //获取与s相关联的全部的顶点,如果邻接的点未被访问,则设置为已被访问且入队 //i是一种list列表的迭代器,用于存储相邻节点的列表 ListIterator<Integer> i = adj[s].listIterator(); while (i.hasNext()){ int n = i.next(); if (!visited[n]){ visited[n]=true; queue.add(n); } } } } public static void main(String[] args) { BreadthFirstSerch g = new BreadthFirstSerch(4); g.addEdge(0,1); g.addEdge(0,2); g.addEdge(1,2); g.addEdge(2,0); g.addEdge(2,3); g.addEdge(3,3); //这个函数只能从指定顶点开始遍历。要是打印所有顶点,可以需要修改BFS函数,逐个从所有节点开始遍历 System.out.println("广度优先遍历从0开始遍历"); g.BFS(0); System.out.println("广度优先遍历从1开始遍历"); g.BFS(1); System.out.println("广度优先遍历从2开始遍历"); g.BFS(2); System.out.println("广度优先遍历从3开始遍历"); g.BFS(3); } } 复制代码
3.深度优先遍历(Depath-First-Search,DFS)
深度优先遍历类似于树的先序遍历。DFS算法是一个递归的算法,需要借助一个递归的工作栈,故它的空间复杂度为O(V)。总的时间复杂度为O(V+E)。
package com.zhoujian.solutions.dataStructure.graph; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; /** * @author zhoujian123@hotmail.com 2018/4/25 21:19 * 图的深度优先遍历:需要借助栈 * 深度优先遍历类似于二叉树的先序遍历 * 使用邻接表表示 * 时间复杂度:当以领接表表示时,查找所有顶点的邻接点所需为O(V),然后每条边至少访问一次所需时间为O(E), * 总的时间复杂度为O(V+E) * */ public class DepthFirstSearch { //顶点的数量 private int V; //邻接表-数组类型的链表 private LinkedList<Integer> adj[]; //构造一个图 DepthFirstSearch(int v){ V = v; //数组链表 adj = new LinkedList[v]; for (int i = 0; i < v; i++) { adj[i]=new LinkedList(); } } //加入与顶点v相连的边v-w void addEdge(int v,int w){ adj[v].add(w); } /** * 从顶点v开始深度遍历 * @param v 顶点v * @param visited 访问标识符 */ void DFSUtil(int v,boolean visited[]){ //把当前节点设置为被访问并打印出来 visited[v]=true; System.out.println(v+" "); ListIterator<Integer> i = adj[v].listIterator(); while (i.hasNext()){ //返回与v相邻的节点 Integer n = i.next(); if (!visited[n]){ DFSUtil(n,visited); } } } void DFS(int v){ //初始化所有顶点并默认为false(数组) boolean[] visited = new boolean[V]; DFSUtil(v,visited); } public static void main(String[] args) { DepthFirstSearch g = new DepthFirstSearch(4); g.addEdge(0,1); g.addEdge(0,2); g.addEdge(1,2); g.addEdge(2,0); g.addEdge(2,3); g.addEdge(3,3); System.out.println("深度优先遍历从顶点2开始"); g.DFS(2); } } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
jQuery实战(第2版)
[美]Bear Bibeault、[美]Yehuda Katz / 三生石上 / 人民邮电出版社 / 2012-3 / 69.00元
jQuery 是目前最受欢迎的JavaScript/Ajax 库之一,能用最少的代码实现最多的功能。本书全面介绍jQuery 知识,展示如何遍历HTML 文档、处理事件、执行动画、给网页添加Ajax 以及jQuery UI 。书中紧紧地围绕“用实际的示例来解释每一个新概念”这一宗旨,生动描述了jQuery 如何与其他工具和框架交互以及如何生成jQuery 插件。 本书适合各层次Web 开发人......一起来看看 《jQuery实战(第2版)》 这本书的介绍吧!