我们在实际的工作业务场景中经常遇到这样的场景,求取树数据中某个节点的父亲节点以及所有的父亲节点,这样的场景下不建议使用深度遍历,使用广度遍历可以更快找到。

1、案例解说

比如树的长相是这样的:

树的数据是这样的:

是我们常用的树的数据及长相。

2、业务要求

在【测试抽取5】后面新增一个节点,要求

1)接口要求传入当前节点的父节点;

2)新增后重新获取树数据,默认展开所有的父级

3、代码实现及说明

思路:

1)设定一个排队数组parentIdsQueue 将树数据开始排队;

2)如果当前数据有孩子节点,将孩子节点倒序加入队列中,因为遍历的时候是从第一个数据开始的;

3)如果当前数据有孩子节点,在孩子加入队列前,把父亲节点的数据放到parentArr中;

4)如果找到了节点,如果是第一层的节点,直接获取即可;如果包括parentArr,则parentArr中的全是它的父级节点

多说无益,先上实现代码

// id 指的是当前点击的节点id;
findParentNode (id) {
// 初始化所需数据
this.firstParentObj = {}; // 记录直系父级的名称和id即接口要传的数据
this.parentIds = []; // 记录所有的父级ids
this.parentIdsQueue = []; // 记录排队的 // 将树放到排队系列
this.parentIdsQueue = this.treeData; // 开始遍历排队的树
while (this.parentIdsQueue.length) {
//抽取第一个排队的数据
let item = this.parentIdsQueue.shift(); let { children } = item;
if (item.id === id) {
// 第一层就找到了
if (!item.parentArr) {
this.firstParentObj = {
id: item.id,
name: item.title
};
this.parentIds = [item.id];
} else {
// 获取当前节点的parentArr
let len = item.parentArr.length;
this.firstParentObj = item.parentArr[len - 1];
item.parentArr.forEach(a => {
this.parentIds.push(a.id);
}); this.parentIds.push(item.id);
} // 结束遍历
this.parentIdsQueue = [];
break;
} else if (children && children.length) {
let len = children.length;
for (let i = len - 1; i >= 0; i--) {
// 新建一个数组用于记录它的父亲节点
children[i].parentArr = []; // 把它的历史父亲节点们先放入
if (item.parentArr) {
children[i].parentArr = children[i].parentArr.concat(
item.parentArr
);
} // 再放入当前的父亲节点
children[i].parentArr.push({
id: item.id,
name: item.title
}); // 加入到排队序列中
this.parentIdsQueue.unshift(children[i]);
}
}
}
}

5、结果演示

我们在文前举的例子中添加个节点,现在来打印出所需的数据

     console.log("测试抽取5的所有父亲",item.parentArr);
console.log("接口所需的父亲节点数据",this.firstParentObj);
console.log("设置树展开所需的所有父亲节点数据节点id", this.parentIds);

如图所示,我们已经实现了相关的功能。至于树的展开,获取的所有的父亲节点,遍历树id在parentIds中的设置其expand为true即可。

记录JS如何使用广度遍历找到节点的所有父节点的更多相关文章

  1. Element ui tree树形控件获取当前节点id和父节点id

    低版本Element ui tree树形控件获取当前节点id和父节点id的方法:点击查看 最新版本Element ui tree树形控件获取当前节点id和父节点id教程: 1.找到node_modul ...

  2. T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

    -- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316-- ...

  3. [SQL]T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

    T-Sql 递归查询(给定节点查所有父节点.所有子节点的方法)   -- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ ...

  4. Treeview控件如何获得子节点的所有父节点的名称

    Delphi或c++ 的treeview控件,比如一个节点上面有个父节点,这个父节点上面还有一个父节点,如何获得这两个父节点的名字呢?请给出实现代码 先定义一个nodevarnode:TTreeNod ...

  5. 遍历DOM树,获取父节点

    通过获取父节点,还可以获取父节点的父节点. 有3个常用方法: 方法  说明  parent()  选取父节点  parents()  选取所有父节点  parentsUntil("div&q ...

  6. easyui Tree模拟级联勾选cascadeCheck,节点选择,父节点自动选中,节点取消,父节点自动取消选择,节点选择,所有子节点全部选择,节点取消,所有子节点全部取消勾选

    最近项目中用到easyui tree,发现tree控件的cascadeCheck有些坑,不像miniui 的tree控件,级联勾选符合业务需求,所以就自己重新改写了onCheck事件,符合业务需求.网 ...

  7. 你真的会玩SQL吗?查询指定节点及其所有父节点的方法

    --查询ID = '009'的所有父节点 ' ;WITH T AS ( SELECT ID , PID , NAME FROM TB WHERE ID = @ID UNION ALL SELECT A ...

  8. javascript : 找到一个树型数据的一个节点及其所有父节点

    如题. (function () { let tree = { "id": 0, "label": "all", "childre ...

  9. extjs4 树列表 添加子节点 刷新所有父节点数据

    itemclick:function(view, record, item,index){console.log(record.parentNode) for(pNode = record.paren ...

随机推荐

  1. 服务器替换san存储

    1.通知DBA停库: 串行登陆服务器 2.备份系统信息 mkdir -p /bakinfo df -h > /bakinfo/df.txt_`date +%Y%m%d%H%M%S` ps -ef ...

  2. ACM团队周赛题解(3)

    940和822两套div.2 老规矩 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0))#define EPS 1e ...

  3. 使用dbutils

    环境准备: 包结构: mysql导出sql脚本: //product CREATE TABLE `product` ( `id` int(10) NOT NULL AUTO_INCREMENT, `n ...

  4. SQL手工注入进阶篇

    0.前言 上一篇我们介绍了SQL手工注入的流程以及步骤,但在实际的安全问题以及CTF题目中,查询语句多种多样,而且是肯定会对用户的输入进行一个安全过滤的,而这些过滤并不一定是百分百安全的,如何利用一些 ...

  5. java数据结构——数组(Array)

    数据结构+算法是我们学习道路上的重中之重,让我们一起进步,一起感受代码之美! /** * 让我们从最基本的数据结构——数组开始吧 * 增.删.改.查.插.显示 */ public class Seql ...

  6. PyCharm设置自己的默认模板

    1.File-Settings 2.Editor- Code Style - File and Code Templates - Python Script 需要设置什么内容,现在就可以写入了,相关变 ...

  7. 抓住那只牛!Catch That Cow POJ-3278 BFS

    题目链接:Catch That Cow 题目大意 FJ丢了一头牛,FJ在数轴上位置为n的点,牛在数轴上位置为k的点.FJ一分钟能进行以下三种操作:前进一个单位,后退一个单位,或者传送到坐标为当前位置两 ...

  8. vuex(vue状态管理)

    vuex(vue状态管理) 1.先安装vuex npm install vuex --save   2.在项目的src目录下创建store目录,并且新建index.js文件,然后创建vuex实例,引入 ...

  9. 死磕 java同步系列之mysql分布式锁

    问题 (1)什么是分布式锁? (2)为什么需要分布式锁? (3)mysql如何实现分布式锁? (4)mysql分布式锁的优点和缺点? 简介 随着并发量的不断增加,单机的服务迟早要向多节点或者微服务进化 ...

  10. layDate——初步使用

    layui系列中layDate的使用教程网址 https://www.layui.com/laydate/ 我这里简单举例: 1.引入js <script type="text/jav ...