java树形递归
- 格式:docx
- 大小:14.35 KB
- 文档页数:6
使⽤Java将⼀个List运⽤递归转成树形结构案例在开发中,我们会遇到将不同组织架构合并成tree这种树状结构,那么如果做呢?实际上,我们也可以理解为如何将拥有⽗⼦关系的list转成树形结构,⽽这其中主要的⽅法就是递归!1、实体对象:@Datapublic class Node {private Integer id;private String city;private Integer pid;private List<Node> children;public Node(Integer id,String city,Integer pid){this.id = id;this.city = city;this.pid = pid;}}2、转换⼯具类:public class TreeUtils {//把⼀个List转成树static List<Node> buildTree(List<Node> list,Integer pid){List<Node> tree=new ArrayList<>();for(Node node:list){if(Objects.equals(node.getPid(),pid)){tree.add(findChild(node,list));}}return tree;}static Node findChild(Node node, List<Node> list){for(Node n:list){if(Objects.equals(n.getPid(),node.getId())){if(node.getChildren() == null){node.setChildren(new ArrayList<Node>());}node.getChildren().add(findChild(n,list));}}return node;}public static void main(String[] args) {Node node0=new Node(0,"中国",-1);Node node1=new Node(1,"湖北省",0);Node node2=new Node(2,"武汉市",1);Node node3=new Node(3,"洪⼭区",2);Node node4=new Node(4,"宜昌市",1);Node node5=new Node(5,"上海市",0);Node node6=new Node(6,"静安区",5);List<Node> list=new ArrayList<>();list.add(node3);list.add(node4);list.add(node1);list.add(node2);list.add(node5);list.add(node6);list.add(node0);List<Node> nodes = buildTree(list,-1);System.out.println(JSON.toJSONString(nodes));}}3、运⾏结果:这样list就成功转换成为了tree装结构到此这篇关于使⽤Java将⼀个List运⽤递归转成树形结构案例的⽂章就介绍到这了,更多相关Java将list运⽤成树形结构内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
java循环和递归在Java编程中,循环和递归是两种常用的控制结构,用于解决重复性的任务和处理递归问题。
循环可以用来重复执行一段代码,而递归则是通过调用自身来解决问题。
本文将介绍Java中的循环和递归的概念、用法和一些常见的应用场景。
一、循环的概念和用法循环是一种重复执行一段代码的控制结构。
在Java中,常见的循环结构有for循环、while循环和do-while循环。
1. for循环for循环是一种在已知循环次数的情况下重复执行一段代码的结构。
它的语法如下:```for (初始化表达式; 循环条件; 更新表达式) {// 循环体}```其中,初始化表达式用于初始化循环变量;循环条件是一个布尔表达式,用于判断是否继续执行循环;更新表达式用于更新循环变量的值。
for循环的执行顺序是先执行初始化表达式,然后判断循环条件,如果为真则执行循环体,然后执行更新表达式,再次判断循环条件,以此类推,直到循环条件为假时结束循环。
for循环的一个常见应用是遍历数组或集合。
例如,可以使用for循环计算数组中元素的总和:```int[] nums = {1, 2, 3, 4, 5};int sum = 0;for (int i = 0; i < nums.length; i++) {sum += nums[i];}System.out.println("数组的总和为:" + sum);```2. while循环while循环是一种在未知循环次数的情况下重复执行一段代码的结构。
它的语法如下:```while (循环条件) {// 循环体}```while循环的执行顺序是先判断循环条件,如果为真则执行循环体,然后再次判断循环条件,以此类推,直到循环条件为假时结束循环。
while循环的一个常见应用是读取用户输入,直到满足特定条件为止。
例如,可以使用while循环验证用户输入的密码是否正确:```import java.util.Scanner;Scanner scanner = new Scanner(System.in);String password = "123456";String input;do {System.out.println("请输入密码:");input = scanner.nextLine();} while (!input.equals(password));System.out.println("密码正确!");```3. do-while循环do-while循环是一种在未知循环次数的情况下重复执行一段代码的结构,与while循环的区别在于它先执行一次循环体,然后再判断循环条件。
java解析四则运算为树形的方法概述及解释说明1. 引言1.1 概述:本文将讨论Java解析四则运算为树形结构的方法。
四则运算是数学中最基础的运算,包括加法、减法、乘法和除法。
通过对四则运算表达式进行解析,可以将其转化为树形结构,以提供更方便的处理和计算方式。
在本文中,我们将介绍四则运算及其解析方式的简介,并重点关注树形结构在这种解析中的应用。
1.2 文章结构:本文共分为5个部分:引言、正文、解释说明、结论和后记。
在引言部分,我们将给出文章的概述,简述整篇文章的内容与目标。
在正文部分,我们将详细介绍四则运算及其解析方式的简介,并探究树形结构在这种解析中的作用。
在解释说明部分,我们会阐述将四则运算表达式转化为树形结构的基本概念和原理,并讨论Java中实现这一过程的方法。
接着,我们还会探讨树形结构在四则运算解析中的优势和应用场景。
在结论部分,我们将总结文章要点和重点论述内容,并对Java解析四则运算为树形的方法进行评价并展望未来的发展方向。
最后,在后记部分,我们将留下一些附加信息和感想。
1.3 目的:本文的目的是提供一个全面且易懂的解析四则运算为树形结构的方法,并探讨这种方法在Java中的应用。
通过深入了解四则运算的解析和树形结构的应用,读者可以更好地理解并使用这些技术,进一步提高程序设计和算法实现能力。
本文还旨在为Java开发者提供一个可靠而有效的工具,以便于他们处理复杂的四则运算表达式。
跟随本文学习并实践这种方法可以增强编码技巧和培养抽象思维能力,在日常开发中收获不少益处。
2. 正文:2.1 四则运算及其解析方式简介:在数学中,四则运算指的是加法、减法、乘法和除法这四种基本运算。
它们是最常见和基础的数学运算,广泛应用于各个领域。
在计算机科学中,我们通常需要将四则运算表达式进行解析,以便计算机能够理解和执行。
2.2 树形结构在四则运算解析中的应用:树形结构是一种非常适合表示嵌套层次关系的数据结构。
部门树形结构算法—Java递归实现将查询到的部门列表数据,进⾏⽗⼦节点树形结构排序该功能适⽤需要树形结构的,不仅仅是部门树步骤:1. 查询数据库,获得所有的部门列表2. 调⽤下⾯的实现⽅法⼀、建表语句CREATE TABLE `dept` (`deptId` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) DEFAULT NULL COMMENT '部门名称',`parentId` bigint(20) DEFAULT NULL COMMENT '⽗级部门ID',PRIMARY KEY (`deptId`)) ENGINE=InnoDB DEFAULT CHARSET=utf8⼆、Java实体类package com.changge.pojo;import java.util.ArrayList;import java.util.List;/*** 部门实体** @author 长歌*/public class Dept {/*** 部门id*/private String deptId;/*** 部门名称*/private String name;/*** ⽗部门id*/private String parentId;/*** ⼦部门*/private List<Dept> children = new ArrayList<>();// get,set等⽅法省略...三、实现⽅法代码/*** 构建前端所需要树结构** @param depts 部门列表* @return 树结构列表*/public List<Dept> buildDeptTree(List<Dept> depts) {List<Dept> deptList = new ArrayList<>();List<String> deptIdList = new ArrayList<>();for (Dept dept : depts) {deptIdList.add(dept.getDeptId());}for (Dept dept : depts) {// 如果是顶级节点,遍历该⽗节点所有⼦节点if (!deptIdList.contains(dept.getParentId())) {recursionFn(depts, dept);deptList.add(dept);}}if (deptList.isEmpty()) {deptList = depts;}return deptList;}/*** 递归列表* 结束条件为所遍历的节点⽆下⼀级节点** @param list 查询获得的所有部门数据* @param dept 顶级节点*/private void recursionFn(List<Dept> list, Dept dept) {// 得到⼦节点列表List<Dept> childList = getChildList(list, dept);dept.setChildren(childList);for (Dept tChild : childList) {// 如果⼦节点有下⼀级节点,得到下⼀级的节点列表if (hasChild(list, tChild)) {recursionFn(list, tChild);}}}/*** 获得该节点的下⼀级⼦节点列表** @param list 查询获得的所有部门数据* @param dept 顶级节点* @return 顶级节点的下⼀级⼦节点列表*/private List<Dept> getChildList(List<Dept> list, Dept dept) {List<Dept> deptList = new ArrayList<>();for(Dept d:list){// 遍历⾮顶级节点,并获得传⼊参数顶级节点的下⼀级⼦节点列表if (d.getParentId() != null && d.getParentId().equals(dept.getDeptId())) { deptList.add(d);}}return deptList;}/*** 判断是否有⼦节点** @param list 节点列表* @param dept 部门节点* @return Boolean*/private boolean hasChild(List<Dept> list, Dept dept) {return getChildList(list, dept).size() > 0;}。
JAVA递归⽣成树形菜单 递归⽣成⼀个如图的菜单,编写两个类数据模型Menu、和创建树形的MenuTree。
通过以下过程实现: 1.⾸先从菜单数据中获取所有根节点。
2.为根节点建⽴次级⼦树并拼接上。
3.递归为⼦节点建⽴次级⼦树并接上,直⾄为末端节点拼接上空的“树”。
⾸先,编写数据模型Menu。
每条菜单有⾃⼰的id、⽗节点parentId、菜单名称text、菜单还拥有次级菜单children。
1import java.util.List;23public class Menu {4private String id;5private String parentId;6private String text;7private String url;8private String yxbz;9private List<Menu> children;10public Menu(String id,String parentId,String text,String url,String yxbz) {11this.id=id;12this.parentId=parentId;13this.text=text;14this.url=url;15this.yxbz=yxbz;16 }17/*省略get\set*/18 } 创建树形结构的类MenuTree。
⽅法getRootNode获取所有根节点,⽅法builTree将根节点汇总创建树形结构,buildChilTree为节点建⽴次级树并拼接上当前树,递归调⽤buildChilTree不断为当前树开枝散叶直⾄找不到新的⼦树。
完成递归,获取树形结构。
1import java.util.ArrayList;2import java.util.List;34public class MenuTree {5private List<Menu> menuList = new ArrayList<Menu>();6public MenuTree(List<Menu> menuList) {7this.menuList=menuList;8 }910//建⽴树形结构11public List<Menu> builTree(){12 List<Menu> treeMenus =new ArrayList<Menu>();13for(Menu menuNode : getRootNode()) {14 menuNode=buildChilTree(menuNode);15 treeMenus.add(menuNode);16 }17return treeMenus;18 }1920//递归,建⽴⼦树形结构21private Menu buildChilTree(Menu pNode){22 List<Menu> chilMenus =new ArrayList<Menu>();23for(Menu menuNode : menuList) {24if(menuNode.getParentId().equals(pNode.getId())) {25 chilMenus.add(buildChilTree(menuNode));26 }27 }28 pNode.setChildren(chilMenus);29return pNode;30 }3132//获取根节点33private List<Menu> getRootNode() {34 List<Menu> rootMenuLists =new ArrayList<Menu>();35for(Menu menuNode : menuList) {36if(menuNode.getParentId().equals("0")) {37 rootMenuLists.add(menuNode);38 }39 }40return rootMenuLists;41 }42 } 最后,插⼊⼀些数据试试效果。
java 树形结构递归过滤Java树形结构递归过滤在Java编程中,树形结构是一种非常常见的数据结构。
它由一系列的节点构成,这些节点按照一定的层次关系连接起来。
树形结构可以用于模拟现实中的各种场景,比如文件系统、组织结构等。
然而,在实际应用中,我们经常需要对树形结构进行一些操作,如搜索、过滤等。
本文将重点讨论如何使用递归来对树形结构进行过滤操作。
第一步:了解树形结构在开始之前,首先要了解树形结构的基本概念。
树形结构由一个根节点和若干个子节点组成,每个节点包含数据以及连接到下一层节点的指针。
节点之间的连接关系遵循一定的层次关系,即每个节点最多有一个父节点和多个子节点。
# 示例:文件系统我们以文件系统为例来说明树形结构的概念。
在文件系统中,根节点表示整个文件系统,它的子节点表示根目录下的所有文件和文件夹。
每个子节点又可以有自己的子节点,构成了一个递归的树形结构。
例如,我们可以构建如下的文件系统树形结构:C:\Program FilesJavajdkbinlibApacheTomcatconflibUsersAliceBob在这个示例中,根节点表示C盘,它有两个子节点Program Files和Users。
以此类推,我们可以进一步展开每个子节点,直到最底层的叶子节点。
第二步:树形结构的递归过滤接下来,我们将树形结构的递归过滤问题进行具体讨论。
假设我们有一个文件系统树形结构,我们想要找出其中所有包含某个关键词的文件或文件夹。
这时,递归过滤就能帮助我们实现这个目标。
# 实现思路首先,我们需要定义一个递归函数来实现树形结构的遍历和过滤操作。
这个函数的输入参数包括当前节点、过滤关键词以及存储结果的数据结构。
函数的主要逻辑如下:1. 判断当前节点是否符合过滤条件,如果是,则将该节点添加到结果中。
2. 判断当前节点是否有子节点,如果有,则递归调用本函数继续遍历子节点。
3. 返回结果。
# 递归函数代码下面是一个简单的递归过滤函数的实现:javapublic void recursiveFilter(Node node, String keyword, List<Node>result) {if (node.getName().contains(keyword)) {result.add(node);}if (node.hasChildren()) {for (Node child : node.getChildren()) {recursiveFilter(child, keyword, result);}}}在这个代码中,我们通过判断节点的名称是否包含给定的关键词来决定是否将该节点添加到结果中。
java树形结构递归实现Java树形结构递归实现树(Tree)是一种常用的数据结构,在计算机技术中扮演着重要的角色。
树状数据结构由根节点,分支节点和叶子节点组成,以树状图准备表示。
树形结构由于具有高效查找,插入和删除的特点,被用于许多不同的数据结构和计算机程序设计。
本文将讨论在java语言中如何使用递归来实现树形结构。
一、为什么要使用递归1、简洁性:递归算法具有更高的理解度,使程序更加简洁;2、可扩展性:递归的特性使它更容易扩展和调整;3、清晰性:递归程序的清晰性以及可读性很高;4、减少代码行数:使用递归可以很好地避免冗余代码,减少代码行数;二、Java语言中树形结构的实现1、类定义:树形结构具有可重用性,因此我们可以创建一个tree类,用于描述树形结构;2、构造方法:构造一个完整的树结构,我们使用Tree constructor,该方法可以初始化树的属性.3、添加节点:为了添加一个新的节点到树,我们必须定义一个addNode方法。
4、获取节点:为了获取树节点的信息,我们定义了一个getNode方法.5、删除节点:为了删除一个树节点,我们定义了一个removeNode方法.6、重新构建:当需要将根节点重新构建为树节点时,我们定义了一个rebuildTree方法.三、递归实现1、使用递归遍历树的深度:当我们遍历树的深度时,我们需要用递归来遍历所有层次的节点,以及节点的子节点。
2、层序遍历:当我们要遍历树的层次时,也可以使用递归的方法。
先遍历第一层的节点,然后递归遍历每一层的子节点。
3、从叶子节点到根节点的遍历:当我们从叶子节点到根节点遍历时,可以采用递归的思想:先从叶子节点遍历,然后递归到节点的父节点,再递归到父节点的父节点,以此类推。
四、结论递归在java中可以有效地实现树形结构。
通过上面的介绍,可以看出,递归的特性使它在实现树形结构上性能优越,并且可以提高代码的可读性和可重用性,为树形结构的使用提供了更大的灵活性和更好的可扩展能力。
java list 树形数据排序方法Java中的List是一种常见的数据结构,它可以存储多个元素,并且可以动态地调整大小。
在实际的开发中,我们经常会遇到需要对树形数据进行排序的需求。
本文将介绍一些常用的方法和技巧,帮助我们对Java List中的树形数据进行排序。
一、树形数据结构简介树形数据结构是一种层次化的数据结构,它由节点和边组成。
每个节点可以有多个子节点,但只能有一个父节点,树形数据结构中的节点之间存在一种层次关系。
常见的树形数据结构有二叉树、多叉树和平衡树等。
二、List中树形数据的排序方法1. 自定义比较器在Java中,我们可以使用自定义比较器来对List中的树形数据进行排序。
比较器是一个实现了Comparator接口的类,它定义了比较两个对象的规则。
我们可以根据树形数据的特点,编写自定义比较器来实现排序。
例如,假设我们有一个树形数据的类TreeNode,它有一个属性value表示节点的值,还有一个属性children表示子节点列表。
我们可以编写一个自定义比较器TreeComparator来比较两个TreeNode对象的大小。
```javapublic class TreeComparator implements Comparator<TreeNode> {@Overridepublic int compare(TreeNode node1, TreeNode node2) {// 比较两个节点的值return node1.getValue().compareTo(node2.getValue());}}```然后,我们可以使用Collections.sort方法来对List中的树形数据进行排序。
```javaList<TreeNode> treeList = new ArrayList<>();// 添加树形数据到List中// ...// 使用自定义比较器进行排序Collections.sort(treeList, new TreeComparator());```2. 递归排序如果树形数据的结构比较复杂,或者我们需要按照多个属性进行排序,可以使用递归排序的方法。
java进阶知识--Lambda表达式、递归⼀、Lambda表达式 1.1 概述 Lambda表达式是JDK 1.8的重量级新特性,它强调做什么,⽽不是以什么形式去做,或者说它强调结果,⽽不是过程。
⽽这种思想我们称之为函数式编程思想。
函数式编程思想与⾯向对象思想的对⽐: ⾯向对象的思想: 做⼀件事情,找⼀个能解决这个事情的对象,调⽤对象的⽅法,完成事情。
函数式编程思想: 只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程。
Lambda的使⽤前提1. 使⽤Lambda必须具有接⼝,且要求接⼝中有且仅有⼀个抽象⽅法。
(有且仅有⼀个抽象⽅法的接⼝,称为“函数式接⼝”。
)⽆论是JDK内置的Runnable、Comparator接⼝还是⾃定义的接⼝,只有当接⼝中的抽象⽅法存在且唯⼀时,才可以使⽤Lambda。
2. 使⽤Lambda必须具有上下⽂推断。
也就是⽅法的参数或局部变量类型必须为Lambda对应的接⼝类型,才能使⽤Lambda作为该接⼝的实例。
1.2 体验Lambda的更优写法 传统写法 当需要启动⼀个线程去完成任务时,通常会通过ng.Runnable接⼝来定义任务内容,并使⽤ng.Thread类来启动该线程。
代码如下:public class DemoRunnable { public static void main(String[] args) { // 匿名内部类 Runnable task = new Runnable() { @Override public void run() { // 覆盖重写抽象⽅法 System.out.println("多线程任务执⾏!"); } }; new Thread(task).start(); // 启动线程 }} Lambda的更优写法 借助Java 8的全新语法,上述Runnable接⼝的匿名内部类写法可以通过更简单的Lambda表达式达到等效:public class DemoLambdaRunnable { public static void main(String[] args) { new Thread(() -> System.out.println("多线程任务执⾏!")).start(); // 启动线程 }} 这两段代码的执⾏效果是完全⼀样的,可以在1.8或更⾼的编译级别下通过。
java 递归满足条件直接跳出整个方法(原创实用版4篇)《java 递归满足条件直接跳出整个方法》篇1在Java 中,递归方法可以通过判断条件来跳出整个方法。
这通常是通过在递归方法中使用`return` 语句来实现的。
当满足特定条件时,直接返回即可跳出递归。
以下是一个简单的递归方法示例,该方法计算阶乘(n! = n * (n-1) * (n-2) *... * 1)。
```javapublic int factorial(int n) {if (n == 0 || n == 1) {return 1;}return n * factorial(n - 1);}```在这个例子中,当`n` 等于0 或1 时,条件满足,方法直接返回1。
这意味着递归过程将在这些条件下停止,从而避免了无限递归导致的Stack Overflow。
《java 递归满足条件直接跳出整个方法》篇2在Java 中,递归方法满足条件后直接跳出整个方法,可以通过在递归方法中添加一个标志变量来实现。
这个标志变量在满足条件时被设置为true,递归方法会在下一次调用前检查这个标志变量,如果为true,则直接返回。
下面是一个简单的递归方法示例,用于计算阶乘:```javapublic class Factorial {public static void main(String[] args) {int n = 5;int result = factorial(n);System.out.println("阶乘" + n + "! = " + result);}public static int factorial(int n) {if (n == 0 || n == 1) {return 1;}int result = 1;for (int i = 2; i <= n; i++) {result *= i;}return result;}}```如果我们想在满足条件时直接跳出整个方法,可以在递归方法中添加一个标志变量,如下所示:```javapublic class Factorial {public static void main(String[] args) {int n = 5;boolean isCancelled = false;int result = factorial(n, isCancelled);if (!isCancelled) {System.out.println("阶乘" + n + "! = " + result);}}public static int factorial(int n, boolean isCancelled) {if (n == 0 || n == 1) {return 1;}int result = 1;for (int i = 2; i <= n &&!isCancelled; i++) {result *= i;}if (isCancelled) {return 0;return result;}}```在这个修改后的示例中,我们添加了一个名为`isCancelled` 的标志变量,并将其传递给递归方法。
java 树形结构递归实现在编程中,树形结构是一种非常常见的数据结构,它由节点和边组成,可以用于表示层次化的数据关系。
在 Java 中,我们可以通过递归来实现树形结构的数据操作。
接下来,我们将逐步介绍如何使用Java 递归来实现树形结构。
1. 定义树的节点类首先,我们需要定义树形结构的节点类。
一个节点类通常包含一个值以及左右子节点。
它的定义如下:```javapublic class TreeNode {int value;TreeNode left;TreeNode right;public TreeNode(int value) {this.value = value;left = null;right = null;}}```2. 插入节点接下来,我们需要实现向树中插入节点的方法。
算法思路是,从根节点开始比较,如果值比当前节点小,在其左子树中查找,否则在右子树中查找。
直到找到一个空位,将新节点插入进去。
实现代码如下:```javapublic void insert(TreeNode root, int value) {if (value < root.value) {if (root.left == null) {root.left = new TreeNode(value);} else {insert(root.left, value);}} else {if (root.right == null) {root.right = new TreeNode(value);} else {insert(root.right, value);}}}```3. 遍历树我们可以使用三种遍历方法来遍历树的节点:先序遍历(preorder):根节点 -> 左子树 -> 右子树中序遍历(inorder):左子树 -> 根节点 -> 右子树后序遍历(postorder):左子树 -> 右子树 -> 根节点以下是先序遍历代码的实现:```javapublic void preorder(TreeNode root) {if (root != null) {System.out.print(root.value + " ");preorder(root.left);preorder(root.right);}}```中序遍历和后序遍历的代码实现也非常类似,读者可以自行尝试实现。
java生成树形结构的方法Java是一种广泛使用的编程语言,在Java中生成树形结构是一项常见的任务。
树形结构是一种层次化的数据结构,由节点和边组成,节点之间的关系呈现出父子关系。
在Java中,可以使用多种方法来生成树形结构,下面将介绍几种常见的方法。
一、使用节点类和边类生成树形结构1. 首先定义一个节点类,节点类包含节点的值和子节点列表。
节点类的定义如下:```javapublic class TreeNode {private int value;private List<TreeNode> children;public TreeNode(int value) {this.value = value;children = new ArrayList<>();}public int getValue() {return value;}public List<TreeNode> getChildren() {return children;}public void addChild(TreeNode child) {children.add(child);}}```2. 然后定义一个边类,边类包含父节点和子节点。
边类的定义如下:```javapublic class TreeEdge {private TreeNode parent;private TreeNode child;public TreeEdge(TreeNode parent, TreeNode child) {this.parent = parent;this.child = child;}public TreeNode getParent() {return parent;}public TreeNode getChild() {return child;}}```3. 最后,使用节点类和边类来生成树形结构。
java递归遍历树形结构
Java递归遍历树形结构是指使用递归算法去遍历一个树形结构。
它可以被应用于各种数据结构,如文件夹目录、XML文档、HTML文档等,甚至可以用于神经网络中的前向传播算法。
首先,要理解什么是树形结构,它是一种分层的有向图,具有根节点、子节点和子节点的孩子节点。
树形结构由节点和边组成,每个节点都有一个父节点,除了根节点。
树形结构中可能有多个子节点,每个子节点又可以有多个孩子节点。
Java递归遍历树形结构的步骤如下:
1. 确定根节点:第一步,需要确定树形结构的根节点,即父节点。
2. 遍历子节点:然后,开始遍历根节点的子节点,并检查每个子节点是否有子节点。
3. 如果有子节点:如果子节点有子节点,则递归地遍历该子节点,直到所有节点均被遍历完毕。
4. 返回父节点:最终,当所有子节点都被遍历完毕,返回父节点,继续遍历其他子节点。
5. 遍历完毕:当根节点的所有子节点都被遍历完毕时,表明整个树形结构已经被遍历完毕。
使用递归遍历树形结构的一个重要好处是,它可以很容易地实现树形结构的深度优先遍历。
也就是说,它可以先深入地搜索树形结构的子节点,然后再回溯父节点,最终完成整个树形结构的遍历。
另外,使用Java构建递归遍历树形结构还有另一个好处,就是可以使用函数式编程(Functional Programming)来实现,允许把功能封装在一个函数中,而不必为每个节点编写代码。
总而言之,Java递归遍历树形结构是一种高效的方法,可以有效地搜索和遍历树形结构中的信息,从而更快地完成某些任务。
java后端递归树,机构树,遍历树public static void getChildrenList(List<JSONObject> list,JSONObject pJo){List<JSONObject> retList=new ArrayList<JSONObject>();for(JSONObject jo:list){if(jo.getString("pid").equals(pJo.getString("id"))){retList.add(jo);jo.put("children", getChildrenList(list, jo));}}//return retList;pJo.put("children",retList);}第⼀种,⽅法循环⼀次,⽐较耗费内存,不建议使⽤public static void main(String[] args) {//拼装数据List<JSONObject> list=new ArrayList<JSONObject>();list.add(JSONObject.parseObject("{id:'1',name:'n1',pid:'-1'}"));list.add(JSONObject.parseObject("{id:'2',name:'n1',pid:'-1'}"));list.add(JSONObject.parseObject("{id:'3',name:'n1',pid:'-1'}"));list.add(JSONObject.parseObject("{id:'1-1',name:'n1-1',pid:'1'}"));list.add(JSONObject.parseObject("{id:'2-1',name:'n2-1',pid:'2'}"));list.add(JSONObject.parseObject("{id:'3-1',name:'n3-1',pid:'3'}"));list.add(JSONObject.parseObject("{id:'1-2',name:'n1-2',pid:'1'}"));list.add(JSONObject.parseObject("{id:'2-2',name:'n2-2',pid:'2'}"));list.add(JSONObject.parseObject("{id:'3-2',name:'n3-2',pid:'3'}"));list.add(JSONObject.parseObject("{id:'1-3',name:'n1-3',pid:'1'}"));list.add(JSONObject.parseObject("{id:'2-3',name:'n2-3',pid:'2'}"));list.add(JSONObject.parseObject("{id:'3-3',name:'n3-3',pid:'3'}"));list.add(JSONObject.parseObject("{id:'1-1-1',name:'n1-1-1',pid:'1-1'}"));list.add(JSONObject.parseObject("{id:'1-1-2',name:'n1-1-2',pid:'1-1'}"));list.add(JSONObject.parseObject("{id:'1-1-3',name:'n1-1-3',pid:'1-1'}"));//递归根节点JSONObject tJo=JSONObject.parseObject("{id:'-1',name:'根节点'}");//tJo.put("children",getChildrenList(list, tJo));System.out.println(tJo.toJSONString());//⼀次循环⽅法,⽐较好内存不建议使⽤Map<String,List<JSONObject>> map1=new HashMap<String, List<JSONObject>>();for(JSONObject jo:list){String pid=jo.getString("pid");String id=jo.getString("id");if(!map1.containsKey(pid)){//不存在map1.put(pid, new ArrayList<JSONObject>());}map1.get(pid).add(jo);if(!map1.containsKey(id)){map1.put(id, new ArrayList<JSONObject>());}jo.put("children", map1.get(id));}JSONObject tJo2=JSONObject.parseObject("{id:'-1',name:'根节点'}");tJo2.put("children", map1.get("-1"));System.out.println(tJo2.toJSONString());}第⼆种⽅法,两次循环,建议使⽤,节省内存public static void main(String[] args) {//拼装数据List<JSONObject> list=new ArrayList<JSONObject>();list.add(JSONObject.parseObject("{id:'1',name:'n1',pid:'-1'}"));list.add(JSONObject.parseObject("{id:'2',name:'n1',pid:'-1'}"));list.add(JSONObject.parseObject("{id:'3',name:'n1',pid:'-1'}"));list.add(JSONObject.parseObject("{id:'1-1',name:'n1-1',pid:'1'}"));list.add(JSONObject.parseObject("{id:'2-1',name:'n2-1',pid:'2'}"));list.add(JSONObject.parseObject("{id:'3-1',name:'n3-1',pid:'3'}"));list.add(JSONObject.parseObject("{id:'1-2',name:'n1-2',pid:'1'}"));list.add(JSONObject.parseObject("{id:'2-2',name:'n2-2',pid:'2'}"));list.add(JSONObject.parseObject("{id:'3-2',name:'n3-2',pid:'3'}"));list.add(JSONObject.parseObject("{id:'1-3',name:'n1-3',pid:'1'}"));list.add(JSONObject.parseObject("{id:'2-3',name:'n2-3',pid:'2'}"));list.add(JSONObject.parseObject("{id:'3-3',name:'n3-3',pid:'3'}"));list.add(JSONObject.parseObject("{id:'1-1-1',name:'n1-1-1',pid:'1-1'}"));list.add(JSONObject.parseObject("{id:'1-1-2',name:'n1-1-2',pid:'1-1'}"));list.add(JSONObject.parseObject("{id:'1-1-3',name:'n1-1-3',pid:'1-1'}"));//递归JSONObject tJo=JSONObject.parseObject("{id:'-1',name:'根节点'}");//tJo.put("children",getChildrenList(list, tJo));System.out.println(tJo.toJSONString());//两次循环⽅法,建议使⽤Map<String,List<JSONObject>> map=new HashMap<String, List<JSONObject>>();for(JSONObject jo:list){String pid=jo.getString("pid");if(!map.containsKey(pid)){//不存在map.put(pid, new ArrayList<JSONObject>());}map.get(pid).add(jo);}for(JSONObject jo:list){String id=jo.getString("id");if(map.containsKey(id)){jo.put("children", map.get(id));}}JSONObject tJo1=JSONObject.parseObject("{id:'-1',name:'根节点'}");tJo1.put("children", map.get("-1"));System.out.println(tJo1.toJSONString());}。
java递归遍历获取子节点的数字之和在Java中,递归遍历树形结构以获取子节点的数字之和是一个常见的任务。
递归是一种编程技术,它允许函数或方法调用自身以解决问题。
在树形结构中,每个节点可能有一个或多个子节点,因此递归遍历是一种非常自然的方式来处理这种结构。
假设我们有一个简单的树形结构,每个节点都有一个整数值,并且每个节点可能有多个子节点。
下面是一个简单的Java类来表示这个树形结构:javaclass TreeNode {int value;List<TreeNode> children;public TreeNode(int value) {this.value = value;this.children = new ArrayList<>();}public void addChild(TreeNode child) {children.add(child);}}接下来,我们可以编写一个递归方法来遍历这个树并获取所有子节点的数字之和:javapublic class TreeSum {public static int getSumOfChildren(TreeNode node) {int sum = 0;// 如果节点为空,返回0if (node == null) {return sum;}// 遍历子节点并累加它们的值for (TreeNode child : node.children) {sum += child.value;// 递归调用以获取子节点的子节点的值sum += getSumOfChildren(child);}return sum;}public static void main(String[] args) {// 创建一个简单的树形结构进行测试TreeNode root = new TreeNode(1);TreeNode child1 = new TreeNode(2);TreeNode child2 = new TreeNode(3);TreeNode grandChild = new TreeNode(4);child1.addChild(grandChild);root.addChild(child1);root.addChild(child2);// 获取子节点的数字之和int sum = getSumOfChildren(root);System.out.println("The sum of children values is: " + sum); // 输出应该是9,因为2 + 3 + 4 = 9}}这个递归方法首先检查当前节点是否为空。
一、简介Java是一种面向对象的程序设计语言,递归是一种解决问题的常用方法,可以通过递归的方式来处理父节点的选中状态。
本文将介绍如何使用Java递归来处理父节点的选中状态,以及一些注意事项和实际应用中的示例。
二、递归处理父节点选中状态的原理1. 父节点选中状态与子节点的关系在树形结构中,父节点的选中状态通常与其子节点的选中状态有关。
当子节点全部选中时,父节点才会被选中;当子节点有部分未选中或全部未选中时,父节点则不应该被选中。
2. 递归调用的实现为了处理父节点的选中状态,我们可以使用递归的方式来遍历树形结构。
当子节点的选中状态发生变化时,可以递归地向上更新父节点的选中状态,直到根节点为止。
三、 Java中的递归处理父节点选中状态的实现1. 定义树形结构的数据模型我们需要定义树形结构的数据模型,通常可以使用树节点的类来表示。
每个树节点包含一个值和一个子节点列表,以及一个选中状态的属性。
2. 递归更新父节点的选中状态当子节点的选中状态发生变化时,可以递归地向上更新父节点的选中状态。
具体实现时,可以使用递归函数来完成这一过程。
四、注意事项1. 避免递归调用的深度过深在实际应用中,递归调用的深度应当受到限制,以避免栈溢出的风险。
可以考虑使用迭代代替递归,或者采用尾递归的方式优化递归调用。
2. 处理循环引用的情况如果树形结构中存在循环引用的情况,递归调用可能会导致无限循环。
在实际应用中,需要考虑如何处理这种情况,以避免程序陷入死循环。
五、实际应用中的示例1. 文件夹结构的表示在文件管理系统中,可以使用树形结构表示文件夹的层次关系。
当用户勾选某个文件夹时,可能需要递归更新其父文件夹的选中状态。
2. 商品类别的多级选择在电商全球信息站中,商品类别通常是多级的,用户可以选择某个类别来浏览商品。
当用户选择某个类别时,可能需要递归更新其所有父类别的选中状态。
六、总结通过本文的介绍,我们了解了如何使用Java递归来处理父节点的选中状态。
如何来做一棵递归树,这在前面的文章中有提过,但那是引用了myfaces组件的,今天就不用啥组件了,直接输出树的结构形状.数据库表数据一样,但还是在此重复一次。
我们的目标是:完成以下形态的树状.--管理---高级管理员----增加----删除----修改---普通管理员----增加一、建表/**--树形菜单节点编号节点名称节点链接址些节点父节点是否最底节点节点排序(一般用在同级节点上)节点说明*/drop table EPTreeTablecreate table EPTreeTable(TreeNodeId int identity(1,1) constraint pk_TreeNode primary key, TreeNodeName varchar(50) not null,TreeNodeLink varchar(100) ,TreeNodeFatherId int default 0, --0 为最高层TreeNodeIsBottom bit default 1, --1 为底层 0为非底层TreeNodeCompositor int default 1, -- 默认排在最后面TreeNodeExplain varchar(200))二、JAVA代码(1)TO对象/*** @author fangbiao* 用于映射父级菜单TO对象*/public class ParentResourcePojo {/*** 节点编号*/private int treeNodeId;/*** 节点名称*/private String treeNodeName;/*** 父节点*/private int treeParentNodeId;/*** @return treeNodeName*/public String getTreeNodeName() {return treeNodeName;}/*** @param treeNodeName 要设置的 treeNodeName*/public void setTreeNodeName(String treeNodeName) {this.treeNodeName = treeNodeName;}/*** @return treeParentNodeId*/public int getTreeParentNodeId() {return treeParentNodeId;}/*** @param treeParentNodeId 要设置的 treeParentNodeId*/public void setTreeParentNodeId(int treeParentNodeId) {this.treeParentNodeId = treeParentNodeId;}/*** @return treeNodeId*/public int getTreeNodeId() {return treeNodeId;}/*** @param treeNodeId 要设置的 treeNodeId*/public void setTreeNodeId(int treeNodeId) {this.treeNodeId = treeNodeId;}}(2)树形组合/*** 获取节点选择列表信息* @return*/public List getResourceList(){if(resourceList.size() == 0) {//获取高级的父节点resourceList = doTurnParentToTree(itbs.getTopParentResource()); }return resourceList;}private int num =2;private int tempTotalChildren ;private boolean temp = false;private int tempParent; //每次递归节点的父节点/*** 对父级列表进行树排* @param prp* @return*/private synchronized List doTurnParentToTree(ParentResourcePojo prp){ if(prp == null)return null;List list = getChildrenList(prp);//分线tempParent = prp.getTreeParentNodeId();String str = "";if(tempParent == 0){resourceList.add("-"+prp.getTreeNodeName()));}else{resourceList.add(prp.getTreeNodeName()));//每棵树的节点数目tempTotalChildren = list.size();}Iterator iterator = list.iterator();while(iterator.hasNext()){ParentResourcePojo treePojo = (ParentResourcePojo)iterator.next();if(tempParent != 0){if( tempParent < treePojo.getTreeParentNodeId()){if(temp == false)num += 1;}else if( tempParent > treePojo.getTreeParentNodeId()){num -=1;temp = false;}else if( tempParent == treePojo.getTreeParentNodeId() ){if(tempTotalChildren ==0)temp = false;elsetemp = true;}}for(int i=0;i<num;i++){str = str + "-";}treePojo.setTreeNodeName(CommonUtil.doAddAppendString(str,treePojo .getTreeNodeName()));str = "";doTurnParentToTree(treePojo);}return resourceList;}/*** 父级菜单列表*/private List allParentTreeList = null;/*** 做标记用*/private int flag = 0;/*** 获取所有父级菜单列表树* @return*/private List getAllParentTreeList(){if(allParentTreeList == null){if(flag == 0){flag = 1;allParentTreeList = itbs.getRRCResource();return allParentTreeList;}return allParentTreeList;}return allParentTreeList;}/*** 取子树列* @param prp* @return*/private List getChildrenList(ParentResourcePojo prp){List list = getAllParentTreeList();int listLength = list.size();List newReturnList = new ArrayList();if(listLength == 0)return newReturnList;List leaveList = new ArrayList();for(int i=0;i<listLength;i++){ParentResourcePojo prPojo = (ParentResourcePojo)list.get(i); int treePojoTreeParantNodeId = prPojo.getTreeParentNodeId(); int tpTreeNodeId = prp.getTreeNodeId();if(treePojoTreeParantNodeId == tpTreeNodeId){newReturnList.add(prPojo);}else{leaveList.add(prPojo);}}list = leaveList;return newReturnList;}到此完成,期间一定要注重同级节点的排序。