【数据结构和算法】--N叉树中,返回某些目标节点到根节点的所有路径

news2024/11/28 5:34:16

目录

  • 一、前言
  • 二、具体实现及拓展
    • 2.1、递归-目标节点到根节点的路径数据
    • 2.2、list转换为tree结构
    • 2.3、tree转换为list结构

一、前言

这么多年工作经历中,“数据结构和算法”真的是超重要,工作中很多业务都能抽象成某种数据结构问题。下面是项目中遇到的一个问题。
业务背景:
在一个复杂的N叉树目录上,通过模糊搜索只返回搜索到的【要返回完整的从root到目标节点】节点链路,以便外围系统直接使用
分析:
按照实际操作,模糊搜索只能搜索到需要的几个目标节点数据,但实际业务需要的是这些目标节点到根节点的结构,以便完美展示。
在这里插入图片描述

问题抽象:
N叉树中,找到所有目标节点到根节点的数据,并构建成tree结构返回。如下图,要返回这些目标节点到根节点的整个路径上的节点数据。
在这里插入图片描述

二、具体实现及拓展

完整的代码如下

 public void filterNodeFromTree(){
        //查询所有的【"有树形结构的"】列表数据
        List<NodeTreeDo> originList = new ArrayList<>();
        Map<String,NodeTreeDo> originMap = originList.stream().collect(Collectors.toMap(NodeTreeDo::getId,ma->ma));
        //目标节点id
        List<String> targetIds = new ArrayList<>();
        Set<String> curRootIdSet = new HashSet<>(); //收集某个目标节点到root的路径经过的所有节点
        for(String id : targetIds){
            if(curRootIdSet.contains(id)) continue;//已经经历过路径,跳过
            curRootIdSet.addAll(collectNeedNode(originMap,id));
        }
        //收集到所有需要的节点的id,然后在过滤多余的
        List<NodeTreeDo> needList = originList.stream().filter(k->curRootIdSet.contains(k.getId())).collect(Collectors.toList());
        //构建成tree
        listToTree(needList);
    }

2.1、递归-目标节点到根节点的路径数据

private Set<String> collectNeedNode(Map<String,NodeTreeDo> originMap,String targetId){
        Set<String> idResultSet = new HashSet<>();
        collectNeedNode(originMap,targetId,idResultSet);
        return idResultSet;
    }

    private boolean collectNeedNode(Map<String,NodeTreeDo> originMap,String targetId,Set<String> idSet){
        if(!originMap.containsKey(targetId)) return false;
        idSet.add(targetId);
        NodeTreeDo cur = originMap.get(targetId);
        return collectNeedNode(originMap,cur.getParentId(),idSet);
    }

2.2、list转换为tree结构

    private List<NodeTreeDo> listToTree(List<NodeTreeDo> originList){
        Map<String, List<NodeTreeDo>> nodeByPidMap = originList.stream().collect(Collectors.groupingBy(NodeTreeDo::getParentId));
        // 循环一次设置当前节点的子节点
        originList.forEach(node -> node.setChildren(nodeByPidMap.get(node.getId())));
        // 获取 一级列表
        return originList.stream().filter(k->"".equals(k.getParentId())).collect(Collectors.toList());
    }

2.3、tree转换为list结构

  private List<NodeTreeDo> treeToList(List<NodeTreeDo> treeList){
        List<NodeTreeDo> resultList = new ArrayList<>();
        for(NodeTreeDo node : treeList){
            getAllListFromChildren(node,resultList);
        }
        return resultList;
    }

    private void getAllListFromChildren(NodeTreeDo node,List<NodeTreeDo> resultList){
        NodeTreeDo copy = CommonUtil.transForm(node,NodeTreeDo.class);
        copy.setChildren(null); //深度拷贝后,把children设置为null
        resultList.add(copy);
        if(CollectionUtils.isNotEmpty(node.getChildren())){
            for(NodeTreeDo temp : node.getChildren()){
                getAllListFromChildren(temp,resultList);
            }
        }
        //没子节点了,自动会退出
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1052602.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MDK报错:Undefined symbol assert_failed报错解决策略

MDK报错&#xff1a;Undefined symbol assert_failed报错解决策略 &#x1f3af;&#x1fa95;在全网搜索相关MDK编译报错:Error: L6218E: Undefined symbol assert_param (referred from xxx.o). ✨有些问题看似很简单&#xff0c;可能产生的问题是由于不经意的细节原因导致。…

16.PWM输入捕获示例程序(输入捕获模式测频率PWMI模式测频率和占空比)

目录 输入捕获相关库函数 输入捕获模式测频率 PWMI模式测频率和占空比 两个代码的接线图都一样&#xff0c;如下 测量信号的输入引脚是PA6&#xff0c;信号从PA6进来&#xff0c;待测的PWM信号也是STM32自己生成的&#xff0c;输出引脚是PA0。 需要配置电路连接图示如下&…

Grafana 开源了一款 eBPF 采集器 Beyla

eBPF 的发展如火如荼&#xff0c;在可观测性领域大放异彩&#xff0c;Grafana 近期也发布了一款 eBPF 采集器&#xff0c;可以采集服务的 RED 指标&#xff0c;本文做一个尝鲜介绍&#xff0c;让读者有个大概了解。 eBPF 基础介绍可以参考我之前的文章《eBPF Hello world》。理…

TrustRadius 评论:为什么 Splashtop 优于 LogMeIn

在当今日益数字化的格局中&#xff0c;远程访问和远程支持工具不仅方便而且至关重要。无论对于居家办公人员&#xff0c;还是对于提供远程支持的 IT 专家&#xff0c;能够安全高效地访问远程系统已成为以技术为导向的日常生活的主要内容。 Splashtop 和 LogMeIn 是远程领域的两…

FFmpeg 命令:从入门到精通 | 查看帮助文档

FFmpeg 命令&#xff1a;从入门到精通 | 查看帮助文档 FFmpeg 命令&#xff1a;从入门到精通 | 查看帮助文档FFmpeg 库模块ffmpeg 命令查看帮助文档ffplay 命令查看帮助文档ffprobe 命令查看帮助文档注意事项 FFmpeg 命令&#xff1a;从入门到精通 | 查看帮助文档 FFmpeg 库模…

【MySQL进阶】--- 存储引擎的介绍

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】&#x1f388; 本专栏旨在分享学习MySQL的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录 一、什么…

数据集笔记:杭州地铁刷卡数据

1 数据位置&#xff1a; 链接: https://pan.baidu.com/s/1iLHomv5NRodB_3jr7FcFow 提取码: arse 全球城市计算AI挑战赛_算法大赛_天池大赛-阿里云天池的赛制 (aliyun.com) 2 数据集介绍 杭州20190101至20190125共25天地铁刷卡数据记录&#xff0c;共涉及3条线路81个地铁站约…

正态分布的概率密度函数|多种正态分布检验|Q-Q图

正态分布的概率密度函数&#xff08;Probability Density Function&#xff0c;简称PDF&#xff09;的函数取值是指在给定的正态分布参数&#xff08;均值 μ 和标准差 σ&#xff09;下&#xff0c;对于特定的随机变量取值 x&#xff0c;计算得到的概率密度值 f(x)。这个值表示…

WPF中的控件

内容控件&#xff1a;label、border Window控件 Label控件 Border控件 内容控件 Button控件 点击取消按钮关闭程序&#xff1b;点击登录按钮打开BorderWindow窗口。 TextBox控件 PasswordBox控件 TextBlock控件 加载窗口时显示TextBlock中的内容 RadioButton控件 CheckBox控件…

WPF 03

staticResource和dynamicResource的区别 首先看一个案例 MainWindow.xaml <Window x:Class"WpfDay03.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml&quo…

【教学类-40-01】A4骰子纸模制作(点数是不同的符号图案)

作品展示 背景需求 骰子是孩子们喜欢的游戏玩具&#xff0c;大3班两个孩子用纸条做了两个迷你的骰子。 所以我想在A4纸上做一个骰子的纸模。 素材准备 WORD模板 隐藏线条、设置实线、虚线、粗线等&#xff0c;慢慢调整&#xff0c;很繁琐 目的&#xff1a; 1、骰子 点数是不…

C++ 类构造函数 析构函数

类的构造函数 类的构造函数是类的一种特殊的成员函数&#xff0c;它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同的&#xff0c;并且不会返回任何类型&#xff0c;也不会返回 void。构造函数可用于为某些成员变量设置初始值。 下面的实例有助于更好地…

Flink之Watermark生成策略

在Flink1.12以后,watermark默认是按固定频率周期性的产生. 在Flink1.12版本以前是有两种生成策略的: AssignerWithPeriodicWatermarks周期性生成watermarkAssignerWithPunctuatedWatermarks[已过时] 按照指定标记性事件生成watermark 新版本API内置的watermark策略 单调递增的…

Android LiveData 介绍

Android LiveData 介绍 系列文章目录前言一、LiveData是什么&#xff1f;二、简单使用依赖测试数据准备1.创建可观察的livedata2.观察它3.更新它 总结 系列文章目录 Android LiveData 介绍&#xff08;本文&#xff09; 前言 本系列根据官网介绍Jetpack中的数据通信组件&…

初识红黑树

文章目录 1.红黑树的介绍1.0红黑树的来源1.1红黑树的概念1.2红黑树的性质 2.红黑树构建示例2.1只变色1.祖父为根/不为根2.连续回溯 2.2变色旋转 3.红黑树构建情况分类3.0默认插入结点颜色3.1情况一:变色1.未知树为空2.未知树不空 3.2情况二:单旋变色1.uncle不存在2.uncle存在为…

FOC控制算法

目录 一、FOC介绍 二、FOC基本概念 1、为什么是三相&#xff1f; 2、FOC矢量控制总体算法简述 3、为什么FOC不一定需要电流采样&#xff1f;参考链接 4、FOC的分类 &#xff08;1&#xff09;有感FOC与无感FOC 三、FOC中电流采样 参考链接 1、高端采样 2、低端采样 …

ChatGPT 学习笔记 | 什么是 Prompt-tuning?

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 Prompt-tuning is an efficient, low-cost way of adapting an AI foundation model to new downstream tasks without retraining the model and upd…

redo日志(下)

title: “redo日志&#xff08;下&#xff09;” createTime: 2022-03-06T15:52:4108:00 updateTime: 2022-03-06T15:52:4108:00 draft: false author: “ggball” tags: [“mysql”] categories: [“db”] description: “” redo log的刷盘时机 log buffer 空间不足时&…

No167.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

通用返回结果类ResultVO

1. 定义通用返回结果类 ​ 定义ResultVO类&#xff0c;作返回给前端的对象结构&#xff0c;主要有4个字段 code : 错误码 data : 内容message : 消息description : 具体描述 import lombok.Data; import java.io.Serializable;/*** 通用返回结果类* param <T>*/ Data …