多级树的深度优先遍历与广度优先遍历(Java实现)

深度优先遍历与广度优先遍历其实是属于图算法的一种,多级树可以看做是一种特殊的图,所以多级数的深/广遍历直接套用图结构的遍历方法即可。

工程中后端通常会用多级树来存储页面表单的各级联动类目,本文提供了深度遍历与广度遍历的示例,在使用时只要根据你的业务需求稍加改动即可。

我们知道,遍历有递归,非递归两种方式。在工程项目上,一般是禁用递归方式的,因为递归非常容易使得系统爆栈。同时,JVM也限制了最大递归数量,在你的树结构非常深的时候很容易出现StackOverflowError异常,所以最好采用非递归的方式。

节点模型

public class Node {
//值
public int value;
//所有的子节点
public ArrayList<Node> nexts; public Node(int value) {
this.value = value;
}
}

深度优先遍历

深度优先搜索英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。多级树可以看做一个特殊的图结构,总的来说遍历的方法还是不变的,都是利用栈和Set来进行操作。

主要步骤:

  1. 准备一个栈结构和一个Set结构的集合,栈用来记录还有孩子没有被遍历到的节点,Set用来记录遍历的历史记录
  2. 将首节点加入到栈和set中
  3. 弹栈拿到首节点
  4. 从首节点开始深度遍历,下面示例代码配合注解近进行理解。
public static void dfs(Node node) {
if (node == null) {
return;
}
Stack<Node> stack = new Stack<>();
HashSet<Node> set = new HashSet<>();
stack.add(node);
set.add(node);
System.out.println(node.value); while (!stack.isEmpty()) {
//弹栈获得一个节点
Node cur = stack.pop();
//查看这个节点的所有孩子
for (Node next : cur.nexts) {
//如果有孩子是之前没有遍历到的,说明这个节点没有深度遍历完
if (!set.contains(next)) {
//此节点与其孩子加入栈与Set中
stack.push(cur);
stack.push(next);
set.add(next);
System.out.println(next.value);
break;
}
}
}
}

广度优先遍历

宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。对于多级数来说,就是先遍历该节点的所有孩子,然后在遍历孩子节点的所有孩子,先遍历一层再遍历下一次层。

主要思路就是利用队列来将下一层的所有节点记录下来,然后顺序遍历就可以了。

public static void bfs(Node node) {
if (node == null) {
return;
}
Queue<Node> queue = new LinkedList<>();
//用来注册已加入队列的节点——>防止重复添加节点
HashSet<Node> set = new HashSet<>();
queue.add(node);
set.add(node);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.println(cur.value);
//将节点的所有下游节点加入到队列
for (Node next : cur.nexts) {
if (!set.contains(next)) {
set.add(next);
queue.add(next);
}
}
}
}

多级树的深度遍历与广度遍历(Java实现)的更多相关文章

  1. 重新整理数据结构与算法(c#)—— 图的深度遍历和广度遍历[十一]

    参考网址:https://www.cnblogs.com/aoximin/p/13162635.html 前言 简介图: 在数据的逻辑结构D=(KR)中,如果K中结点对于关系R的前趋和后继的个数不加限 ...

  2. java遍历树(深度遍历和广度遍历

    java遍历树如现有以下一颗树:A     B          B1               B11          B2               B22     C          C ...

  3. 图的存储及遍历 深度遍历和广度遍历 C++代码实现

    /*图的存储及遍历*/ #include<iostream> using namespace std; //----------------------------------- //邻接 ...

  4. 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图

    二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...

  5. c/c++连通图的遍历(深度遍历/广度遍历)

    连通图的遍历(深度遍历/广度遍历) 概念:图中的所有节点都要遍历到,并且只能遍历一次. 深度遍历 广度遍历 深度遍历 概念:从一个给定的顶点开始,找到一条边,沿着这条边一直遍历. 广度遍历 概念:从一 ...

  6. Java多线程遍历文件夹,广度遍历加多线程加深度遍历结合

    复习IO操作,突然想写一个小工具,统计一下电脑里面的Java代码量还有注释率,最开始随手写了一个递归算法,遍历文件夹,比较简单,而且代码层次清晰,相对易于理解,代码如下:(完整代码贴在最后面,前面是功 ...

  7. Dom的深度优先遍历和广度优先遍历

    //深度优先遍历的递归写法 function DFTraversal(node) { var nodes = []; if (node != null) { nodes.push(node); var ...

  8. 数据结构5_java---二叉树,树的建立,树的先序、中序、后序遍历(递归和非递归算法),层次遍历(广度优先遍历),深度优先遍历,树的深度(递归算法)

    1.二叉树的建立 首先,定义数组存储树的data,然后使用list集合将所有的二叉树结点都包含进去,最后给每个父亲结点赋予左右孩子. 需要注意的是:最后一个父亲结点需要单独处理 public stat ...

  9. 数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)

    前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...

随机推荐

  1. 在vue中监听storage的变化

    1.首先在main.js中给Vue.protorype注册一个全局方法,其中,我们约定好了想要监听的sessionStorage的key值为’watchStorage’,然后创建一个StorageEv ...

  2. 邮件服务配置(虚拟域&虚拟用户)

    邮件服务配置(虚拟域&虚拟用户) 现在我做的是: Linux + httpd + php + mariadb + postfix + dovecot + phpMyAdmin + postfi ...

  3. 基于JaCoCo的Android测试覆盖率统计(二)

    > 本文章是我上一篇文章的升级版本,详见地址:https://www.cnblogs.com/xiaoluosun/p/7234606.html ## 为什么要做这个?1. 辛辛苦苦写了几百条测 ...

  4. S2:log4j

    配置步骤 1.引入jar,放到lib中,jar包被项目管理 2.在src目录下copy了一个文件log4j.properties 3.使用Logger   String word="会员登记 ...

  5. Nginx + Lua 搭建网站WAF防火墙

    前言 对于项目里面只是使用代理等常用功能,在线安装即可,如需制定化模块,则推荐编译安装 PS:本文不仅仅包含Nginx相关的知识点,还包含了逆天学习方法(对待新事物的处理) 官方网站:https:// ...

  6. 运营商手机视频流量包业务日志ETL及统计分析

    自己做过的项目在这里做一个记录,否则就感觉不是自己的了.一是因为过去时间已经很长了,二是因为当时做得有点粗糙,最后还不了了之了. 话不多说,先大致介绍一下项目背景.以前各大手机视频 App 一般都有运 ...

  7. 深扒JVM,对它进行“开膛破肚”式解析!

    1. 打怪升级,你绕不开JVM JVM,对Java程序员进阶而言,是一个绝对绕不开,也不能绕开的话题. 在你打怪升级.进阶蜕变的路上,势必会遇到项目上线中各种OOM.GC等问题,此时JVM的功底就至关 ...

  8. Java高级面试题解析(二):百度Java面试题前200页(精选)

    基本概念 操作系统中 heap 和 stack 的区别 heap是堆,stack是栈,是两种不同的数据结构.堆是队列优先,先进先出:栈是先进后出. 在java多线程中,每个线程都有自己的栈:不同的线程 ...

  9. RocketMQ中PullConsumer的消息拉取源码分析

    在PullConsumer中,有关消息的拉取RocketMQ提供了很多API,但总的来说分为两种,同步消息拉取和异步消息拉取 同步消息拉取以同步方式拉取消息都是通过DefaultMQPullConsu ...

  10. pythonday06数据类型(四)

    今日内容 1.集合 2内存相关 1.集合set 无序 无重复 v = {1,2,3,4,5,6,99,100} # 疑问:v = {} """ None int v1 = ...