1. 程式人生 > >記錄JS如何使用廣度遍歷找到節點的所有父節點

記錄JS如何使用廣度遍歷找到節點的所有父節點

我們在實際的工作業務場景中經常遇到這樣的場景,求取樹資料中某個節點的父親節點以及所有的父親節點,這樣的場景下不建議使用深度遍歷,使用廣度遍歷可以更快找到。

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) {
          this.parentIds = [];
          // 第一層就找到了
          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);

相關推薦

PHP 通過一個節點所有節點

如圖,拿到所有給出節點的父節點。百度搜了半天,都是通過父節點找子節點的。無奈,後來只能自己寫了。遍歷+遞迴,大神們不要鄙視我。。。我資料結構。。。<?php //測試資料 $arr = [ ['id'=>8,'pid'=>7,'username'=&

記錄JS如何使用廣度找到節點所有節點

我們在實際的工作業務場景中經常遇到這樣的場景,求取樹資料中某個節點的父親節點以及所有的父親節點,這樣的場景下不建議使用深度遍歷,使用廣度遍歷可以更快找到。 1、案例解說 比如樹的長相是這樣的: 樹的資料是這樣的: 是我們常用的樹的資料及長相。 2、業務要求 在【測試抽取5】後面新增一個節點,要求 1)

js遞迴陣列獲取所有的葉子節點

var arr=[];function queryList(json,arr) { for (var i = 0; i < json.length; i++) { var

遞迴xml檔案所有節點

由於xml格式並不是固定的,xml檔案示例僅作示範,xml節點的深度變化,有點像N叉樹結構,需要採用遞迴演算法: <?xml version="1.0" encoding="UTF-8"?> <TestPackage appNameSpace="com.sprd.an

js陣列迴圈陣列內所有元素的方法

在js中陣列遍歷最簡單的辦法就是使用for然後再利用arr.length長度作為for最大限度值即可解決了,下面我們來看看一些有用的例項 例,for(){}遍歷陣列 <script type="text/javascript">  <!-- var

【程式碼重構 & JDT】AST,獲取每個節點所有直接子節點

public class DataNode { public ASTNode node; //所代表的的AST節點 public int label; //編號 public List<Integer> childrenLables = new ArrayL

【程式碼重構 & JDT】AST,獲取每個節點所有直接子節點

public class DataNode { public ASTNode node; //所代表的的AST節點 public int label; //編號 public List<Integer> childrenLables = new ArrayList<>

js深度、廣度 dom樹

// 深度遍歷 function interator(node) { console.log(node); if (node.children.length) { fo

js對象所有的屬性名稱和值

site com pro ref asc var 名稱 cap 中文 /* * 用來遍歷指定對象所有的屬性名稱和值 * obj 需要遍歷的對象 * author: Jet Mah * website: http://www.javatang.com/archiv

圖的廣度和深度

初始化 -- fin num 方法 技術分享 else 全部 nts /* 圖的遍歷方法主要有兩種:一種是深度優先遍歷。一種是廣度優先遍歷。圖的深度優先遍歷類同於樹的先根遍歷。圖的廣度遍歷類同樹的層次遍歷 一:連通圖的深度優先遍歷算法 圖的深度優先遍歷算法是遍歷

數據結構-深度廣度(轉)

指針 void 邊表 當前 初始化 循環隊列 logs == ont 本文轉自http://blog.csdn.net/wingofeagle/article/details/13020373 深度遍歷: 從圖中某個頂點v出發,訪問此頂點,然後從v的未被訪問的鄰接點出發

存儲所有物體添加到列表中(使用GameObject.activeSelf進行判斷)

data des button menus add image game tac self //存儲菜單列表 List<GameObject> subMenu = new List<GameObject>(); //存儲所有子菜單 pu

Java包中所有類方法註解

|| asm 服務器 ret nec next 代碼 自定義 tco 一.代碼實例 import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.l

03鄰接矩陣的深度和廣度的C語言實現

返回 算法 ++ 其它 連通圖 edge main fin site #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define

[轉載]Python遞歸目錄下所有文件

cnblogs 需要 os.walk ext 包含 mage ring wal exe #自定義函數: import ospath="D:\\Temp_del\\a"def gci (path):"""this is a statement"""parents = os.l

react.js map的問題

his 字符 click 改變 ima 相同 掛載 ant stat React遍歷多個Ant Design中的Upload組件時,隨意刪除任一個Upload出現了bug,依次點擊上傳圖片後,當點擊刪除時,倒著刪除沒有問題,從中間和從開頭刪問題出現了,出現了類似塌方的效果,

【練習】字典的循環:實現多層級節點存取

輸入 lose 功能 print path input 內存地址 sleep pat 關鍵點:字典、列表、集合等可變類型,若將一個可變類型賦給變量A和B,通過B改變了該可變類型內部的元素,指向該可變類型內存地址的變量A的值一樣會跟著改變(因A、B同時指向了一個內存地址)

js註冊事件時索引怎麽獲取

遍歷註冊單擊事件 索引註意:這種寫法,是有問題的。註冊事件是在頁面加載完畢以後就完成了,但此時並沒有觸發事件。事件觸發是由用戶在頁面上點擊時才會觸發,所以說當用戶點擊時,才會執行事件處理函數,那麽此時的i已經變成了4,最後最終彈出來的結果是i+1,也就是5,而且每一個元素的彈出來的結果都是5。此時的做法應該是

js如何並取出對象的屬性名?

height 遍歷 dir pre obj var name 18C ole js如何遍歷並取出對象的屬性名? dataObj = {name : su,age : 26,height : 18cm }; for(var st in dataObj) {console.di

js常用匯總

匯總 web nbsp var 返回值 continue 用法 dev reac 1, for(let i of Array) for( let i of arr){ console.log(i); } ES6新增的,i代表每次循環Array的值,相當於Arra