記錄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) {
          // 第一層就找到了
          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即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM