当前位置: 首页 > 知识库问答 >
问题:

java怎么用递归返回树结构的结果?

郗学
2023-11-13

一、想要实现的效果

- 以搜索“秦朗为例”,最后返回的是 三国-曹操-秦朗 的一条链路(一棵树)。


二、我的代码
public class People {

private List<People> children;private String name;// 省略getter、setter方法

}
public static void main(String[] args) {

    People sunce = new People();    sunce.setName("孙策");    People sunquan = new People();    sunquan.setName("孙权");    People sunjian = new People();    sunjian.setName("孙坚");    sunjian.setChildren(Arrays.asList(sunce, sunquan));    People caopi = new People();    caopi.setName("曹丕");    People caozhi = new People();    caozhi.setName("曹植");    People caozhang = new People();    caozhang.setName("曹彰");    People qinlang = new People();    qinlang.setName("秦朗");    People caocao = new People();    caocao.setName("曹操");    caocao.setChildren(Arrays.asList(caopi, caozhi, caozhang, qinlang));    People liufeng = new People();    liufeng.setName("刘封");    People liushan = new People();    liushan.setName("刘禅");    People liubei = new People();    liubei.setName("刘备");    liubei.setChildren(Arrays.asList(liufeng, liushan));    People liuxun = new People();    liuxun.setName("刘循");    People liuzhang = new People();    liuzhang.setName("刘璋");    liuzhang.setChildren(Arrays.asList(liuxun));    People liuyan = new People();    liuyan.setName("刘焉");    liuyan.setChildren(Arrays.asList(liuzhang));    People sanguo = new People();    sanguo.setName("三国");    sanguo.setChildren(Arrays.asList(sunjian, caocao, liubei, liuyan));    List<People> p1 = query(sanguo, "刘");    System.out.println(p1);    List<People> p2 = query(sanguo, "秦");    System.out.println(p2);    List<People> p3 = query(sanguo, "孙策");    System.out.println(p3);}public static List<People> query(People people, String name) {    List<People> result = new ArrayList<>();    // 这里要判空,但简写就省略了    if(people.getName().contains(name)) {        return Arrays.asList(people);    } else {        if(people.getChildren() != null) {            for (People p : people.getChildren()) {                result.addAll(query(p, name));            }        }    }    return result;}

三、代码执行结果

四、解释
我递归用的少,用起来有点不达意。上面自己写的递归方法虽然能实现递归效果,但问题很大。
4.1、我的方法返回的只是命中项,而不是一个树的结构(除非第一层就命中了)。
4.2、返回的树里没有剔除未命中项。

上述两点(4.1和4.2)能否同时做到?如果不能,请指教怎么实现4.1,感谢。

共有1个答案

秦俊友
2023-11-13

这个问题可以通过使用递归和合适的数据结构来解决。在Java中,我们可以使用树结构(或者更具体地说,是树的列表)来存储每个人物及其子女的信息。然后,我们可以使用递归来查找从根节点到目标节点的路径。

为了实现你的需求,你可能需要对你的People类进行一些修改。尤其是,你需要为每个人物维护一个子节点列表,而不是仅仅为曹操和刘备。同时,你需要创建一个方法来构建这个树结构。以下是一个可能的实现:

import java.util.*;public class People {    private String name;    private List<People> children;    public People(String name) {        this.name = name;        this.children = new ArrayList<>();    }    public void addChild(People child) {        this.children.add(child);    }    public String getName() {        return this.name;    }    public List<People> getChildren() {        return this.children;    }}

然后,你可以在main方法中创建树结构:

public static void main(String[] args) {    // 创建节点    People sunjian = new People("孙坚");    People sunce = new People("孙策");    People sunquan = new People("孙权");    sunjian.addChild(sunce);    sunjian.addChild(sunquan);    People caocao = new People("曹操");    People caopi = new People("曹丕");    People caozhi = new People("曹植");    People caozhang = new People("曹彰");    caocao.addChild(caopi);    caocao.addChild(caozhi);    caocao.addChild(caozhang);    caocao.addChild(qinlang); // 这里需要添加 qinlang 节点,但你的代码中没有提供创建它的方法,我在这里添加它以便下面的代码可以运行。    // ... 其他节点创建方法类似,不再赘述。    // 构建树结构    People sanguo = new People("三国");    sanguo.addChild(sunjian);    sanguo.addChild(caocao);    // ... 添加其他节点 ...}

接下来,你可以使用递归方法来查找从根节点到目标节点的路径。以下是一个可能的实现:

public static List<People> query(People people, String name) {    List<People> result = new ArrayList<>();    if (people == null) {        return result;    } else if (people.getName().equals(name)) { // 找到目标节点,返回当前节点及其所有子节点(包括子节点的子节点等)        result.add(people);        result.addAll(people.getChildren()); // 包括当前节点的所有子节点。递归调用 query 方法,继续查找子节点的子节点。
 类似资料:
  • 我一直在用这个四叉树http://www.astroml.org/book_figures/chapter2/fig_quadtree_example.html 在一些数据上。但是我现在需要结果结构的嵌套表示。 其结构类似于: 这里的子元素是递归元素,它是一个列表,包括进一步的实例。最低深度没有子级(为0),是我想要访问的表示。因此,在这种情况下,我会访问数据 最终,我希望在最低级别的数据表示像:

  • 问题内容: 我有一个将位置链接在一起的数据库表;一个位置可以在一个位置,也可以在另一个位置内。 这是深入探讨MySQL / PHP的深度: 在给定父级位置的情况下,如何使用MySQL如何获得其所有后代位置,无论深度如何? 问题答案: mysql.com上有 一篇漂亮的文章 ,概述了管理分层数据的各种方法。我认为它为您的问题提供了完整的解决方案,并显示了各种不太简单但较快的方法(例如嵌套集)。

  • 翻到祖师爷代码,发现树结构的数据是后端通过递归去生成的,效率非常低,请问有什么方法可以优化吗?

  • 本文向大家介绍数据结构 二叉树的递归与非递归,包括了数据结构 二叉树的递归与非递归的使用技巧和注意事项,需要的朋友参考一下 数据结构 二叉树的递归与非递归 实例代码:  先序遍历(递归法)   后序遍历      感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • 我现在正在实现模拟N体问题的Barnes-Hut算法。我只想问关于建筑树的部分。 我做了两个函数来为它构建树。 我递归地构建树,并在构建时打印每个节点的数据,一切看起来都是正确的,但当程序返回到主函数时,只有树的根和根的子节点存储值。其他节点的值没有被存储,这很奇怪,因为我在递归过程中打印了它们,它们应该被存储。 这是经过修改的代码的一部分,我认为问题可能在哪里: 下面是函数set_root_an

  • 本文向大家介绍Java递归遍历树形结构的实现代码,包括了Java递归遍历树形结构的实现代码的使用技巧和注意事项,需要的朋友参考一下 废话不多说了,直接给大家贴代码,具体代码如下所示: ps:java实现树的递归遍历(用于实现折叠菜单) 1.核心算法 2.实体类(部门) 以上所述是小编给大家介绍的Java递归遍历树形结构的相关内容,希望对大家有所帮助! 更多精彩内容请关注公众号【Java技术迷】,可