python 树结构 转换 list

阅读: 评论:0

python 树结构 转换 list

python 树结构 转换 list

背景

之前写了一篇列表转树的文章,有列表转树的需求自然就会有树转列表的需求,这里我把树转列表的思路与代码再整理一下。

思路分析

需求是什么?

老规矩,上图

先说一下整体思路,就是遍历树中的每一个节点,在遍历过程中要把节点的父节点id记录下来,并作为该节点的parentId属性值(保留层级关系,后续根据这个parentId和节点的id可以转回树结构),然后把该节点存入一个列表中。遍历过程完成,也就实现了把树结构转换成了列表结构。

树的遍历方式有两种,一种是深度优先遍历,一种是广度优先遍历,这两种方式思路如下图所示:

广度优先:

深度优先

思路看这两个图应该理得清楚了

我这里深度优先遍历采用了递归的方式,然后广度优先遍历采用了循环的方式。

执行步骤

先说深度优先吧:

从第一层开始遍历,遍历该层中所有节点,为每一个遍历到的节点添加上parentId属性,存入结果列表。

每一个遍历节点存入结果列表后,检测该节点是否存在子节点,如果存在,则将子节点作为数据源重复第一步

当所有的节点都处理完成后,整个树结构也就完成了转化

再说说广度优先:

从第一层开始遍历,遍历该层中所有节点,为每一个遍历到的节点添加上parentId属性,存入结果列表。

每一个遍历节点存入结果列表后,检测该节点是否存在子节点,如果存在,则将子节点数据项push到第一层遍历的列表中(这里相当于在for循环的过程中,修改了被遍历的数组的内容,在循环过程中把它变长了)

当所有的节点都处理完成后,整个树结构也就完成了转化

代码

深度优先

/*

* 深度优先遍历树

* 一个递归方法

* @params tree:要转换的树结构数据

* @params list:保存结果的列表结构数据,初始传[]

* @params parentId:当前遍历节点的父级节点id,初始为null(因为根节点无parentId)

* */

function toListDF (tree, list, parentId = null) {

for (let node of tree) {

list.push({

id: node.id,

name: node.name,

children: [],

parentId

})

if (node.children.length !== 0) {

toList(node.children, list, node.id)

}

}

}

广度优先:

/*

* 广度优先遍历树

* 一层循环

* @params tree:要转换的树结构数据

* @output list:返回转换好的列表结构数据

* */

function toListBF (tree) {

const tempList = tree.slice(0)

const res = []

for (let node of tempList) {

// 向结果中push每一个节点的数据

res.push({

id: node.id,

name: node.name,

children: [],

parentId: node.parentId === undefined ? null : node.parentId

})

// 如果该节点还有子节点,那么将子节点追加到待循环列表的后面

if (node.children.length !== 0) {

// 这里注意,push的是children里面的项

tempList.push(...node.children.map((item) => {

// 这里给每一项加上parentId

item.parentId = node.id

return item

}))

}

}

return res

}

这里给一个简单的树结构数据用来测试

const tree = [

{

id: 0,

name: 'root',

children: [

{

id: 1,

name: 'child1',

children: [

{

id: 4,

name: 'child1-1',

children: []

},

{

id: 5,

name: 'child1-2',

children: []

}

]

},

{

id: 2,

name: 'child2',

children: [

{

id: 6,

name: 'child2-1',

children: [

{

id: 8,

name: 'child2-1-1',

children: []

}

]

}

]

},

{

id: 3,

name: 'child3',

children: [

{

id: 7,

name: 'child3-1',

children: []

}

]

}

]

}

]

上面代码直接扔到浏览器中即可运行,可自行看看结果。

总结

树转列表过程中,我这里的深度优先采用了递归方式,可能会对内存占用较多,使用时请自行权衡。

在广度优先的方式中,只用了一层循环,这里有一个核心的点,就是js在循环列表过程中,被循环的列表是可以修改的,比如push一个数据项,这样会让for循环多运行一次,这个点理解之后,我这里的广度优先遍历树的方法就好理解了。

本文发布于:2024-01-28 23:59:37,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170645757811246.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:结构   python   list
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23