获取树形json中的某个节点_树形化 Parent-Child 数组

本文介绍了如何从Parent-Child数组中获取树形JSON的特定节点,并详细讲解了通过建立映射表来优化时间复杂度,避免递归爆栈问题的实现方式,最后总结了该方法的空间换时间优化策略。
摘要由CSDN通过智能技术生成

f0c52288df5d98355c86b7dea6dbb1cf.png

1. 前言

最近在写一些东西,需要存储一些系统的菜单到数据库。 id 标识当前菜单,pid 标识父级菜单,这样将一个系统的菜单目录存储到数据。获取到某一个系统的所有菜单,得到的数据可以简化成 Parent-Child 的一个数组,而返回给调用方,是需要做一个树形化的结构。

2. 模型

[
	[1, 0],
	[2, 1],
	[3, 4],
	[4, 2],
	[5, 0],
]

上述一个数组中,0 是一个没有任何意义的菜单,一个虚拟的根级菜单,1 表示菜单 1,它的父级菜单是 0,那么 1 就是一个一级菜单。[2 1] 表示菜单 2 的父级菜单是菜单 1,那么 2 就是 二级菜单。其表示的树形结构如下;

70a23260cbbdfbd7c95e09aac8cc6b40.png

3. 实现

因为知道 0 是根节点,找到 0 节点,再找出其所有子节点,然后递归改节点。如上图,如果该树形结构是一个单叉树的话,数组 length 过大的话,递归会爆栈的,且其时间复杂度 O(n^2)。那么有没有更好一点的方法呢。

首先,代码如何表示一个树形结构,大部分的编程语言都是用指针或者引用来实现。父节点持有子节点的指针或引用。那我们将定义一个 Node 节点。

type  Node struct {
      Resource             *PermNode   `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
      Child                []*Node `protobuf:"bytes,2,rep,name=child,proto3" json:"child,omitempty"`
}

c1f9b3877a9c0c4fc9072e6da0019e86.png

我们初始化一个 map,记录遍历过的节点。

直接遍历数组,拿到数组每个元素,进而知道其 id 和 pid。

id 节点在 map 中不存在,直接添加到 map;id 节点存在的话,取出该节点。两种情况都将节点信息补全。

pid 节点在 map 中不存在的,直接添加到 map;pid 节点存在的话,取出该节点。两种情况都将 id 节点的指针 append 到 pid 节点的 child 中,关联起来。

1)id 节点添加到 map 时,没有 child 信息,没有关系,如果下次遍历到,会取出该节点,补全其信息的;如果遍历不到,说明该节点是一个叶子节点。

2)pid 节点添加到 map 中的时候,节点信息为空。没有关系,下次遍历到该节点再补全其节点信息。

3)使用 map 存储这些节点是为了方便取出该节点。

4. 总结

其实是用了空间换时间,这种方式是一种常规的算法优化的思路。js 的实现会更简单方便。

如有错误,请批评指正。如有更好的方法,请告知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值