【数据结构和算法】--N叉树中,批量的目标节点到根节点的路径

目录

  • 一、前言
  • 二、代码
    • 2.1、Bean对象定义
    • 2.2、实现代码

一、前言

在N叉树中,返回某些目标节点到根节点的所有路径这篇文章中,已经介绍一种查询目标节点到根节点的路径方法。现在思考用另一种方法去实现这个问题。

二、代码

2.1、Bean对象定义

public class ImprovedDoublyListNode {Set<String> idSet;Map<String,LinkedNode> idNodeMap;public ImprovedDoublyListNode(){}public ImprovedDoublyListNode(LinkedNode node){if(null == idSet){idSet = new HashSet<>();}if(null == idNodeMap){idNodeMap = new HashMap<>();}while (node != null) {idSet.add(node.cur_id);idNodeMap.put(node.cur_id,node);node = node.next;}}class LinkedNode {String cur_id;LinkedNode next;LinkedNode prev;public LinkedNode(String cur_id) {this.cur_id = cur_id;this.next = null;this.prev = null;}}
}

2.2、实现代码

把树形tree结构的数据,转换为双向链表后,能更快速找到“到根节点的链路”。

    //将所有叶子节点到根节点的路径转化为双向链表
public List<ImprovedDoublyListNode.LinkedNode> convertToDoublyLinkedLists(NodeTreeDo root) {List<ImprovedDoublyListNode.LinkedNode> result = new ArrayList<>();if (root == null) return result;// 遍历树并为每个叶子节点创建双向链表dfs(root, null, result);return result;}// 深度优先遍历树,构建双向链表
private void dfs(NodeTreeDo node, ImprovedDoublyListNode.LinkedNode head, List<ImprovedDoublyListNode.LinkedNode> result) {// 如果节点没有子节点,则是叶子节点if (CollectionUtils.isEmpty(node.getChildren())) {// 叶子节点,构建双向链表ImprovedDoublyListNode.LinkedNode listNode = new ImprovedDoublyListNode(). new LinkedNode(node.getId());// listNode.add(node.getId(),listNode);listNode.next = head; // 链接当前节点到链表头部if (head != null) {head.prev = listNode; // 设置双向链表的prev指针}result.add(listNode); // 将链表头节点加入结果列表return;}// 递归遍历子节点ImprovedDoublyListNode.LinkedNode currentNode = new ImprovedDoublyListNode(). new LinkedNode(node.getId());// currentNode.add(node.getId(),currentNode);currentNode.next = head; // 将当前节点添加到链表的头部if (head != null) {head.prev = currentNode; // 设置双向链表的prev指针}for (NodeTreeDo child : node.getChildren()) {// 递归调用DFS,遍历子节点dfs(child, currentNode, result);}}/*** * @param originNodeList* @return*/
public List<ImprovedDoublyListNode> convertListNode(List<ImprovedDoublyListNode.LinkedNode> originNodeList){List<ImprovedDoublyListNode> improvedList = originNodeList.stream().map(k->new ImprovedDoublyListNode(k)).collect(Collectors.toList());return improvedList;}/*** 输入任意节点id,找寻 到根节点的path* @param improvedList* @param inputId* @return*/
public ImprovedDoublyListNode.LinkedNode findNodePath(List<ImprovedDoublyListNode> improvedList,String inputId){ImprovedDoublyListNode.LinkedNode link = null;for(ImprovedDoublyListNode temp : improvedList){if(temp.idSet.contains(inputId)){//只要找到一个就可以link = temp.idNodeMap.get(inputId);break;}}return link;}/*** 转换为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());}

测试方法

 NodeTreeDo root = new NodeTreeDo("", "1", "Root");NodeTreeDo root1 = new NodeTreeDo("", "1.2", "Root111");NodeTreeDo child1 = new NodeTreeDo("1", "2", "Child 1");NodeTreeDo child2 = new NodeTreeDo("1", "3", "Child 2");NodeTreeDo child3 = new NodeTreeDo("2", "4", "Child 3");NodeTreeDo leaf1 = new NodeTreeDo("4", "5", "Leaf 1");NodeTreeDo leaf2 = new NodeTreeDo("4", "6", "Leaf 2");NodeTreeDo leaf3 = new NodeTreeDo("2", "2.1", "Child 4");NodeTreeDo leaf4 = new NodeTreeDo("2.1", "2.2", "Child 4");// 构建全部的list结构List<NodeTreeDo> rootList = new ArrayList<>();rootList.add(root);rootList.add(child1);rootList.add(child2);rootList.add(child3);rootList.add(leaf1);rootList.add(leaf2);rootList.add(leaf3);rootList.add(leaf4);rootList.add(root1);TreeToDoublyLinkedList solution = new TreeToDoublyLinkedList();List<NodeTreeDo> newRootList = solution.listToTree(rootList); //转换成树结构//每个叶子节点到根节点的链路improvedListList<ImprovedDoublyListNode> improvedList = new ArrayList<>();for(NodeTreeDo node : newRootList){List<ImprovedDoublyListNode.LinkedNode> result = solution.convertToDoublyLinkedLists(node);List<ImprovedDoublyListNode> oneList = solution.convertListNode(result);improvedList.addAll(oneList);}

在上面improvedList是每个叶子节点到根节点的链路,假设有一批目标节点targetIds,需要找到这些节点到根节点的路径

for(String teId : targetIds){ImprovedDoublyListNode.LinkedNode link = solution.findNodePath(improvedList,teId);// 打印path内容while (link != null) {System.out.print(link.cur_id + "->");link = link.next;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins Nginx Vue项目自动化部署

目录 一、环境准备 1.1 Jenkins搭建 1.2 NVM和Nodejs安装 1.3 Nginx安装 二、Jenkins配置 2.1 相关插件安装 2.2 全局工具安装 2.3 环境变量配置 2.4 邮箱配置&#xff08;构建后发送邮件&#xff09; 2.5 任务配置 三、Nginx配置 3.1 配置路由转发 四、部署项目 …

BASLER工业相机维修不能触发拍照如何处理解决这个问题

BASLER工业相机维修不能触发拍照如何处理解决这个问题&#xff1f;最近遇到挺多工业相机维修咨询这个不能触发拍照的案例&#xff0c;所以今天优米佳维修的技术就抽空整理了这篇关于BASLER相机不能触发拍照的处理方法分享给大家。 当碰到巴斯勒工业相机不能触发拍照的问题&…

68000汇编实战01-编程基础

文章目录 简介产生背景应用领域 语言学习EASy68K帮助文档IDE使用 编程语言commentslabels开始标签指令标签位置标签 opcode 操作码常用操作码数据传送算术运算逻辑运算控制流分支跳转地址跳转子程序跳转 位操作比较堆栈操作 IO操作码其他操作码 directives 指令DC指令EQU 指令S…

wsl2的Ubuntu18.04安装ros和anaconda

参考&#xff1a;超详细 WSL2 安装 ros 和 anaconda_wsl2安装anaconda-CSDN博客 一.安装ros 1. 更换系统源 输入 wget http://fishros.com/install -O fishros && . fishros 和上面的链接一样&#xff0c;依次输入5-2-1 2. 安装ros 输入 wget http://fishros.c…

如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间

如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间 一、引言二、检查当前磁盘和分区状态1. 使用 `df` 命令检查磁盘使用情况2. 使用 `lsblk` 命令查看分区结构3. 使用 `fdisk` 或 `parted` 命令查看详细的分区信息三、扩展逻辑卷(如果使用 LVM)1. 检查 LVM …

【Linux打怪升级记 | 报错02】-bash: 警告:setlocale: LC_TIME: 无法改变区域选项 (zh_CN.UTF-8)

&#x1f5fa;️博客地图 &#x1f4cd;1、报错发现 &#x1f4cd;2、原因分析 &#x1f4cd;3、解决办法 &#x1f4cd;4、测试结果 1、报错发现 装好了CentOS操作系统&#xff0c;使用ssh远程登陆CentOS&#xff0c;出现如下告警信息&#xff1a; bash: 警告:setlocale…

【数据结构】双向链表、单向循环链表、双向循环链表、栈、链栈

目录 一、双向链表 定义类和封装函数以及测试样例如下&#xff1a; 注意事项&#xff1a; 二、循环链表 单循环列表的类和函数封装如下&#xff1a; 注意事项&#xff1a; 三、双向循环链表 结点类和双循环链表的定义部分 函数封装之判空和尾插 双循环链表遍历 双循…

week 6 - SQL Select II

Overview 1. Joins 包括交叉连接&#xff08;Cross&#xff09;、内连接&#xff08;Inner&#xff09;、自然连接&#xff08;Natural&#xff09;、外连接&#xff08;Outer&#xff09; 2. ORDER BY to produce ordered output 3. 聚合函数&#xff08;Aggregate Functio…

systemverilog约束中:=和:/的区别

“x dist { [100:102] : 1, 200 : 2, 300 : 5}” 意味着其值等于100或101或102或200或300其中之一&#xff0c; 其权重比例为1:1:1:2:5 “x dist { [100:102] :/ 1, 200 : 2, 300 : 5}” 意味着等于100&#xff0c;101&#xff0c;102或200&#xff0c;或300其…

[Python/网络安全] Git漏洞之Githack工具基本安装及使用详析

前言 本文仅分享Githack工具基本安装及使用相关知识&#xff0c;不承担任何法律责任。 Git是一个非常流行的开源分布式版本控制系统&#xff0c;它被广泛用于协同开发和代码管理。许多网站和应用程序都使用Git作为其代码管理系统&#xff0c;并将其部署到生产环境中以维护其代…

NFT Insider #157:The Sandbox 开启新一期 VoxEdit 比赛

市场数据 加密艺术及收藏品新闻 Artnames 项目上线&#xff0c;将用户姓名转化为个性化 NFT 艺术品 由知名数字艺术家 Arrotu 发起的生成艺术项目「Artnames」正式上线&#xff0c;利用区块链技术将用户姓名转化为独一无二的 NFT 艺术品。该项目于 11 月 14 日启动&#xff0…

计算机是如何工作的

1. 冯诺依曼体系 CPU 中央处理器: 进行算术运算和逻辑判断 存储器: 分为外存和内存, 用于存储数据(使用二进制方式存储) 输入设备: 用户给计算机发号施令的设备 输出设备: 计算机个用户汇报结果的设备 1&#xff09;针对存储空间&#xff1a; 硬盘 > 内存 >> CPU …

简单好用的折线图绘制!

折线图的概念及作用&#xff1a; 折线图&#xff08;Line Chart&#xff09;是一种常见的图表类型&#xff0c;用于展示数据的变化趋势或时间序列数据。它通过一系列的数据点&#xff08;通常表示为坐标系中的点&#xff09;与这些点之间的线段相连&#xff0c;直观地展示变量…

【拥抱AI】Milvus 如何处理 TB 级别的大规模向量数据?

处理 TB 级别的大规模向量数据是 Milvus 的核心优势之一。Milvus 通过分布式架构、高效的索引算法和优化的数据管理策略来实现这一目标。下面将详细介绍 Milvus 如何处理 TB 级别向量数据的流程&#xff0c;包括插入代码示例、指令以及流程图。 1. 分布式架构 Milvus 使用分…

Scrapy管道设置和数据保存

1.1 介绍部分&#xff1a; 文字提到常用的Web框架有Django和Flask&#xff0c;接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分&#xff1a; Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…

k8s集群部署metrics-server

1、Metrics Server介绍 Metrics Server 是集群级别的资源利用率数据的聚合器。从 Kubelets收集资源指标&#xff0c;并通过 Metrics API 在 Kubernetes apiserver 中公开它们&#xff0c;以供 Horizontal Pod Autoscaler 和Vertical Pod Autoscaler 使用。 Metrics API 也可以…

什么是串联谐振

比如有一个由电阻、电容和电感的串联电路中&#xff0c;存在一个频率能使这个电路的电流最大&#xff0c;这个现象就叫谐振。 那么这个频率是多少呢&#xff1f; 交流电频率与电路固有频率一致时&#xff0c;它就能发生谐振&#xff0c;此时这个电路的电流是最大的 这个固有频…

(vue)启动项目报错The project seems to require pnpm but it‘s not installed

(vue)启动项目报错The project seems to require pnpm but it’s not installed 原因 该错误信息表明你的项目需要使用 pnpm 作为包管理工具&#xff0c;但系统中尚未安装 pnpm。 解决方法 【1】删除pnpm.lock 【2】npm install -g pnpm 之后再重新启动 yarn报错&#xff0…

Laravel8.5+微信小程序实现京东商城秒杀方案

一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案&#xff08;3种&#xff09; 下单减库存 优点是库存和订单的强一致性&#xff0c;商品不会卖超&#xff0c;但是可能导致恶意下单&#xff…

JVM:即时编译器,C2 Compiler,堆外内存排查

1&#xff0c;即时编译器 1.1&#xff0c;基本概念 常见的编译型语言如C&#xff0c;通常会把代码直接编译成CPU所能理解的机器码来运行。而Java为了实现“一次编译&#xff0c;处处运行”的特性&#xff0c;把编译的过程分成两部分&#xff0c;首先它会先由javac编译成通用的…