首页 > 编程语言 >通过递归算法对执行栈的理解

通过递归算法对执行栈的理解

时间:2022-12-01 10:22:11浏览次数:59  
标签:上下文 name 递归 list pid 算法 理解 执行 id

通过递归算法对执行栈的理解

在工作中经常遇到树形结构的场景,数据的类型大致分为两类 1. [{children: [...]}]这种list children的形式, 2. [{id: 1}, {parentId: 1}]构成的{id: 1, children: { parentId: 1 }}这种形式,

如果是数据1 的这种结构,就使用递归遍历数据即可,对于数据2 则需要先将打平的数据转化为 数据1 的格式。

将下面结构转为树形结构

[
  {
    id: 1,
    pid: '',
    name: '北京市'
  },
  {
    id: 2,
    pid: 1,
    name: '海淀区'
  },
  {
    id: '2-2',
    pid: 2,
    name: '知春路'
  },
  {
    id: '2-3',
    pid: 2,
    name: '中关村'
  },
  {
    id: '2-1',
    pid: 2,
    name: '西二旗'
  },
  {
    id: 3,
    pid: 1,
    name: '昌平区'
  },
  {
    id: '3-1',
    pid: 3,
    name: '回龙观'
  },
  {
    id: '3-2',
    pid: 3,
    name: '朱辛庄'
  },
  {
    id: 4,
    pid: 1,
    name: '朝阳区'
  },
  {
    id: '4-2',
    pid: 4,
    name: '三元桥'
  },
]
function arrToTree(list, rootValue) {
  let treeData = [] // 新建数组 , 用来储存当前对象的子对象
  list.forEach(item => {
      // 遍历寻找子对象
      if (item.pid === rootValue) {
          // 递归  返回对象的children列表
          const children = arrToTree(list, item.id)
          // 如果有children就将数组添加给对象
          if (children.length) {
              item.children = children
          }
          // 将完整的item添加给导出的数组
          treeData.push(item)
      }
  })
  return treeData // 每次递归会返回当前的子列表
}

const treeData = arrToTree(list, '')

上面执行 过程中,首先创建全局的执行栈 arrToTree 执行的时候, push 到执行栈中,在它的作用域内遍历list, 判断 list中元素的pid 是不是等于传入的rootValue 如果等于, 就递归执行 arrToTree, 将新的 rootValue 传入,生成一个新的函数作用域,push 到执行栈中, 依次递归执行,一直到 不满足 item.pid === rootValue ,函数执行完 返回 treeData 然后 pop 出执行栈。

如果还是不清楚,可以按照下面的思路 自己理解下
1. 创建全局执行栈
2. arrToTree 函数push 到执行栈 函数接收的参数是 list, '' .下面元素

{
    id: 1,
    pid: '',
    name: '北京市'
  },

满足条件,所以递归执行了arrToTree 参数为 list, 1
3. arrToTree 函数push 到执行栈 此时执行栈是这样的

[全局上下文,第二部函数执行上下文, 第三步函数执行上下文]

此时还是遍历list
下面元素

{
    id: 2,
    pid: 1,
    name: '海淀区'
  },

满足条件, 所以递归执行了arrToTree 参数为 list, 2
4. arrToTree 函数push 到执行栈
此时执行栈是这样的

[全局上下文,第二部函数执行上下文, 第三步函数执行上下文,第四步函数上下文]

此时还是遍历list
下面元素

{
    id: '2-2',
    pid: 2,
    name: '知春路'
  },

满足条件,所以递归执行了arrToTree 参数为 list, 2-2
5. arrToTree 函数push 到执行栈
此时执行栈是这样的

[全局上下文,第二部函数执行上下文, 第三步函数执行上下文,第四步函数上下文,第五步函数上下文]

此时还是遍历list , 这个时候 没有元素满足条件 所以函数返回了[]. 并且将该上下文 pop 出执行栈 也就回到了第四步执行上下文, 第四步中的 treeData 应为第五步返回的是空数组就push 了

{
    id: '2-2',
    pid: 2,
    name: '知春路'
  },

在第四步的上下文中继续遍历 第二个符合条件的是

{
    id: '2-3',
    pid: 2,
    name: '中关村'
  },

递归执行了arrToTree 参数为 list, 2-3
在执行栈中添加新的上下文,继续执行,发下没有满足条件的,返回了空数组, 再pop 出执行栈,然后应为返回的是空数组, 所以将元素中关村的内容 也push 到 第四步的执行上下文 treeData,

接着遍历 发现 西二旗 的内容也满足, 重复上面的步骤,最后 返回第四步的上下文后,此时 treeData 中有 知春路,中关村,西二旗三组数据,第四步上下文没有满足条件的情况下 返回 treeData ,将第四步上下文 pop 出执行栈, 来到第三步执行栈, 应为返回的treeData.length > 0 给该执行栈 当前元素 海淀区 创建一个key ="children" ,value= treeData

第三步执行栈中接着遍历, 发现下一个满足条件的元素 name 为 昌平区 ,重复上面第四步的步骤
。。。
第三步执行栈中接着遍历, 发现下一个满足条件的元素 name 为 朝阳区 ,重复上面第四步的步骤

第三步上下文执行完后,pop 出执行栈,返回 trueData

没有满足第三步条件的情况下, 将 第三步上下文 pop 出执行栈

接着执行 第二部执行栈 最后执行完后 再pop 出执行栈,

到全局执行栈的时候, 也就返回了最终的结果

下面是我的小程序体验码,希望能和大家共同学习进步

标签:上下文,name,递归,list,pid,算法,理解,执行,id
From: https://www.cnblogs.com/eyesstar/p/16940595.html

相关文章

  • 算法竞赛入门【码蹄集进阶塔335题】(MT3330-3335)
    算法竞赛入门【码蹄集进阶塔335题】(MT3330-3335)(文章目录)前言为什么突然想学算法了?>用较为“官方”的语言讲,是因为算法对计算机科学的所有分支都非常重要。在绝......
  • 算法竞赛入门【码蹄集进阶塔335题】(MT2326-2330)
    算法竞赛入门【码蹄集进阶塔335题】(MT2326-2330)(文章目录)前言为什么突然想学算法了?>用较为“官方”的语言讲,是因为算法对计算机科学的所有分支都非常重要。在绝......
  • 每日算法之调整数组顺序使奇数位于偶数前面(一)
    JZ21调整数组顺序使奇数位于偶数前面(一)描述输入一个长度为n整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的......
  • Java HashMap 在获得 Key 的 Hash 值的时候用的是什么算法
    Java在HashMapKey的Hash值的时候用的的是自己Object中的hashCode()算法。返回的结果是一个整数值。如果你查看JDK的源代码的话,在HashMap类中会有下面的这......
  • 经典算法——最短路径(Floyd+Dijkstra)
    Floyd时间复杂度:O(n^3)简介:作为最短路算法中复杂度最高的算法没有之一,标志性结构三层循环,核心结构本质DP思想具 有动态规划的无后效性他真的没有优点啦?!不,他有!虽然SPF......
  • 常用代码模板1——基础算法
    常用代码模板1——基础算法快速排序算法模板voidquick_sort(intq[],intl,intr){if(l>=r)return;inti=l-1,j=r+1,x=q[l+r>>1];......
  • 算法基础-搜索
    搜索框架dfs框架#include<bits/stdc++.h>usingnamespacestd;constintN=100005;structNode{charvalue;intlson,rson;}tree[N];......
  • 最小生成树算法及其常见应用
    最小生成树定义:在无向图\(G=(V,E)\)中,一颗连接所有节点的树(无根树)被称为这个无向图的生成树,其中边权之和最小的那一颗被称为最小生成树定理:最小生成树一定包含无向图中......
  • 最短路算法及其常见扩展应用
    第一节——最短路问题基本概念:由于无向边可以看作两条相反的有向边,于是我们默然按照有向边的形式讨论存图方式:邻接矩阵:空间复杂度\(O(n^2)\),优点:\(O(1)\)查找\(x->y\)......
  • 观察 | 边缘云计算的概念理解
    6月27日-28日,全国信标委云计算标准工作组边缘云计算技术及标准研讨会在京成功召开。BoCloud博云作为云计算标准工作组成员与来自全国信标委云计算标准工作组、中国开源云联......