深度优先搜索和广度优先搜索

​ 在人工智能的运筹学的领域中求解与图相关的应用中,这两个算法被证明是非常有用的,而且,如需高效地研究图的基本性质,例如图的连通性以及图是否存在环,这些算法也是必不可少的。

深度优先搜索

​ 深度优先搜索可以从任意顶点开始访问图的顶点,然后把该顶点标记为已访问,在每次迭代中,该算法紧接着处理与当前顶点邻接的未访问的顶点。这个过程一直持续,直到遇到一个终点——该顶点的所有邻接点都已经被访问过。在该终点上,该算法沿着来路后退一条边,并试着继续从哪里访问未访问的顶点,在后退到起始顶点,并起始顶点也是一个终点时,该算法最终停了下来。这样起始顶点所在的连通分量的所有顶点都被访问过了。如果未访问的顶点仍然存在,该算法必须从其中任一顶点开始,重复上述过程。

​ 用一个来跟踪深度优先搜索的操作是比较方便的。在第一次访问一个顶点时,我们把该顶点入栈,当它成为一个终点时,我们把它出栈。

Java实现深度优先搜索:

boolean [] visited;
/**
* @Description: 从n开始进行的深度优先遍历
* @return: 返回结果
* @Author: Mr.Gao
* @Date: 2021/2/15
*/
public void result(int n,DenseGraph denseGraph){int node = denseGraph.findNode();visited = new boolean[node];Stack<Integer> stack = new Stack<>();stack.push(n);while(!stack.empty()){int temp = stack.pop();visited[temp]=true;System.out.print(temp+" ");for (int i = 0; i < node; i++) {if(visited[i]==false&&denseGraph.getG()[temp][i]==true){stack.push(i);}}}
}
  • 这里的DenseGraph是我们实现的稠密图的类。专门用于实现稠密图。

稠密图代码:

/*** @program:算法库* @description:稠密图的创建,使用邻接矩阵*/
public class DenseGraph {private int edge;           //边数private int node;           //节点数private boolean direction;  //是否为有向图private boolean[][] g;      //图的具体数据public boolean[][] getG() {return g;}public DenseGraph(int node, boolean direction){assert node>=0;         //一个断言this.node = node;this.direction = direction;this.g = new boolean[node][node];}//返回边数public int findEdge(){return edge;}//返回节点数public int findNode(){return node;}//为图添加一条边public void addEdge(int p,int q){assert p>=0&&p<node;assert q>=0&&q<node;if(hasEdge(p,q)){return;}g[p][q]=true;if(!direction){g[q][p]=true;}edge++;}//检验p到q是否有一条边public boolean hasEdge(int p,int q){assert p>=0&&p<node;assert q>=0&&q<node;return g[p][q];}
}
  • 稠密图我们使用邻接矩阵实现,而稀疏图我们使用邻接链表进行实现

稀疏图的类代码:

import java.util.Vector;/*** @program:算法库* @description:稀疏图的创建,使用邻接链表,这里我们规定从自己到自己有一条默认路径。*/public class SparseGraph {private int node;           //节点数private int edge;           //边数private boolean direction;  //是否为有向图private Vector<Integer>[] g;//图的具体数据public SparseGraph(int node,boolean direction){assert node>=0;         //设置一个断言this.node = node;this.direction = direction;this.g = (Vector<Integer>[]) new Vector[node];for (int i = 0; i < node; i++) {g[i] = new Vector<Integer>();}}//返回边的个数public int findEdge(){return edge;}//返回节点个数public int findNode(){return node;}//添加一条从p到q的边public void addEdge(int p ,int q){assert p>=0&&p<node;assert q>=0&&q<node;assert p!=q;if(!hasEdge(p,q)){g[p].add(q);if(!direction){g[q].add(p);}}edge++;}public boolean hasEdge(int p,int q){assert p>=0&&p<node;assert q>=0&&q<node;if(p==q){return true;}for (int i = 0; i < g[p].size(); i++) {if(g[p].elementAt(i)==q){return true;}}return false;}}

广度优先搜索:

​ 如果说深度优先搜索表现出来的是一种勇气,那么广度优先搜索表现出来的就是一种严谨。它按照一种同心圆的方式,首先访问所有和初始顶点邻接的顶点,然后是离它两条边的所有未访问顶点,以此类推,直到所有与初始顶点同在一个连通分量中的顶点都访问过了为止,如果仍然存在未被访问的顶点,该算法必须从图的其他连通分量中的任意顶点重新开始。

​ 使用队列来跟踪广度优先搜索的查找是方便的。该队列先从遍历的初始顶点开始,将该顶点标记为已访问,在每次迭代中,该算法找出所有和队头顶点邻接的未访问顶点,把它们标记为已访问,再把它们入队。然后将队头顶点从队列中移走。

Java实现:

boolean[] visited;
/**
* @Description: 使用邻接矩阵实现广度优先搜索
* @return:  返回结果
* @Author: Mr.Gao
* @Date: 2021/2/15
*/
public void result(int n,DenseGraph denseGraph){int node = denseGraph.findNode();visited = new boolean[node];Queue<Integer> queue = new LinkedList<>();queue.add(n);while(!queue.isEmpty()){int temp = queue.poll();System.out.print(temp+" ");visited[temp] = true;for (int i = 0; i < node; i++) {if(visited[i]==false&&denseGraph.getG()[temp][i]==true){queue.add(i);}}}
}
  • 最后附上深度优先搜索和广度优先搜索的主要性质
  • 我太菜了

深度优先搜索和广度优先搜索相关推荐

  1. 八数码深度优先搜索_深度优先搜索和广度优先搜索

    深度优先搜索和广度优先搜索 关于搜索&遍历 对于搜索来说,我们绝大多数情况下处理的都是叫 "所谓的暴力搜索" ,或者是说比较简单朴素的搜索,也就是说你在搜索的时候没有任何所 ...

  2. 算法十——深度优先搜索和广度优先搜索

    文章出处:极客时间<数据结构和算法之美>-作者:王争.该系列文章是本人的学习笔记. 搜索算法 算法是作用于数据结构之上的.深度优先搜索.广度优先搜索是作用于图这种数据结构之上的.图上的搜索 ...

  3. 深度优先遍历和广度优先遍历_图与深度优先搜索和广度优先搜索

    什么是图? 图是一种复杂的非线性表结构.由若干给定的点一级任意两点间的连线所构成.图通常用来描述事物之间的特定关系, 代表的就是事物, 线就是事物之间所具有的关系.例如社交网络就是一种典型的图关系, ...

  4. 数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)

    目录 一.图的遍历概念 二.深度优先搜索(DFS) (一)DFS算法步骤 1.邻接表DFS算法步骤 2.邻接矩阵DFS算法步骤 (二)深度优先生成树.森林 (三)DFS的空间复杂度和时间复杂度 三.广 ...

  5. 迷宫问题:深度优先搜索和广度优先搜索

    迷宫问题:深度优先搜索和广度优先搜索 1.深度优先搜索可以使用栈实现,栈顶元素为当前节点 2.当前节点搜索下一节点,判断节点是否走得通,如果走得通任意方向走一步,走不通一直弹出栈内元素,直到走得通 3 ...

  6. 学会二叉树不知道干啥?二叉树的深度优先搜索和广度优先搜索,我要打十个乃至二十个(打开你的LeetCode撸起来)学练并举

    目录 一. 图解二叉树的深度优先搜索 二. 二叉树的广度优先搜索  (层序遍历) 三. 打开LeetCode 撸起来 至此, 咱多少被刚刚的后序非递归搞得可能有点小晕晕的, 没事,层序简单呀....  ...

  7. 深度优先搜索与广度优先搜索区别和案例

    今天周末,心血来潮打开LeetCode做一道题: https://leetcode-cn.com/problems/number-of-enclaves/ 看到题,我的第一想法是: 从边缘的陆地开始, ...

  8. 根据邻接表求深度优先搜索和广度优先搜索_深度优先搜索/广度优先搜索与java的实现...

    度:某个顶点的度就是依附于该顶点的边的个数 子图:一幅图中所有边(包含依附边的顶点)的子集 路径:是由边顺序连接的一系列定点组成 环:至少含有一条边且终点和起点相同的路径 连通图:如果图中任一个到另一 ...

  9. 深度优先搜索和广度优先搜索的比较与分析

    一)深度优先搜索的特点是: (1)无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生 ...

最新文章

  1. oracle触发器高级教程
  2. Oracle 技巧篇-快速批量删除当前数据库连接的用户,一键清空所有session会话方法
  3. oracle php 配置,PHP + Oracle的配置
  4. JSON转换工具---jackson
  5. 在django中使用vue.js需要注意的地方
  6. 未来五年,iOS 开发如何前行?
  7. c#抽取pdf文档标题(1)
  8. python接口自动化登录后保存个人简介_python接口自动化三(登录及发帖)
  9. 手把手教你Windows环境下配置Git环境
  10. MFC字符串CString分割函数 简洁 C++
  11. 如何制作频数折线图(详细)
  12. java技术栈是什么_java技术栈必学有哪些?
  13. 编译原理(整体理解)
  14. java读取sheet2_java读取Excel指定sheet页或全部sheet页数据(含2003和2007版本)
  15. Shamir秘密共享协议
  16. css img 等比例自动缩放
  17. Vue开发之基础路由
  18. 【Spring AOP】静态代理设计模式、Spring 动态代理开发详解、切入点详解(切入点表达式、切入点函数)
  19. 注册Outlook如何跳过手机验证
  20. 向单片机flash中烧录自定义数据的方法

热门文章

  1. 计算机红外,红外光谱
  2. 2022年双十一百亿补贴,2022年聚划算双11玩法解读
  3. string类型--字符串常用取值操作
  4. 基于单目视觉的同时定位与地图构建方法综述
  5. 培训:3天带你快速上手Kubernetes | 上海站
  6. 风清清,雨霖霖,青剑低啸吟,月色如银
  7. 大数据能否解决城市所面临的环境问题
  8. mysql根据id分页_MySQL_MSSQL根据ID进行分页实现方法,复制代码 代码如下: ALTER PROCEDU - phpStudy...
  9. 迷路的奶牛 Farmer John C++
  10. openwrt重启后,修复dns