BlessingCR’s Blog
BlessingCR’s Blog

部门树问题

部门树问题

今天遇到一个很有意思的问题,很常见而且有点难度。

开发中肯定会有一些2b的平台会有公司架构,每个公司又有不同的部门树。

现需求为

```Plain Text

  1. 部门树深度不能超过5层,即,如果往第五层子部门添加部门,应该报错
  2. 部门允许移动,也就是部门A允许带着A下面所有部门一起随A移动到部门B, 注意,此处需要满足条件1, 如不满足,拒绝此次移动
  3. 部门没有其他限制,也就是不限制数量,同时允许CURD,(删除的时候有子部门不允许删除)
    
    需求非常简单而且常见,看着也很好实现,但是开发中,发现难度挺高,无法实现,起码无法高性能的实现

其中最难的地方就在于树的嫁接(部门移动)
部门移动的时候, 由于有树深度的限制,所以需要满足部门B的层数+(A最深子节点的层数-A的层数) <= 5
方式1(从上到下):
考虑部门表维护一个路径图, 描述根节点到自己的路径。
如:

https://blessingcr.com/wp-content/uploads/2023/11/捕获-1.png

drawio

某节点10, 则存储路径为 1,2,5,6,10
此时,如果判断某节点A是否可移动到节点B,只需要判断节点B的层数(可以通过路径得知)+ 节点A最深子节点的深度(可以通过数据库查询与节点A路径匹配的子节点,并循环得到最大深度)。
此时判断是否可移动为O(n)时间复杂度,同时此方案查询,删除,新增时间复杂度均很低。
但问题在于移动以后,所有子节点的路径均需要全部维护一遍,并且部门这个树是一个多叉树,这意味着移动以后,时间复杂度最差情况为更新每一个子节点路径信息,这对数据库压力过大。

方案一不可行(同理,维护节点的层级也不可行)

方案二(从下到上):
维护每一个节点的子节点最大深度,如上图中,节点5子节点最大深度为2,节点8子节点最大深度为1,节点10子节点最大深度为0.

该方案节点A移动到节点B时,只需要递归节点B的父节点(最高5层),即可判断是否可以移动。

这个方案问题在于,移动以后,节点A原本的所有父节点,他的层级关系改变了,也就是所有他的父节点最深深度变了,那么就不得不维护从根节点开始,整个树的所有节点的子节点最大深度。

方案二不可行

在我们百思不得其解之际,我们找到PM,PM给我们看了他抄的网站。网站确实支持这种部门树的移动,但是不会有部门层数的限制,我们想起来,部门层数限制这个是当时考虑到联查有性能问题而拒绝的。我们后续思考,可以通过限制部门的最大数目,而非深度来约束时间复杂度。

也就是说,其实并未解决此题,但是把限制一的深度限制去掉,即可简单实现该需求,是否又更好的方法,期待留言。

发表回复

textsms
account_circle
email

  • 匿名

    ???

    7 月前 回复
  • I love your writing style truly enjoying this web site.

    2 月前 回复
  • I will right away grasp your rss as I can not to find your e-mail subscription hyperlink or e-newsletter service. Do you have any? Kindly let me recognise so that I may subscribe. Thanks.

    1 月前 回复

BlessingCR’s Blog

部门树问题
部门树问题 今天遇到一个很有意思的问题,很常见而且有点难度。 开发中肯定会有一些2b的平台会有公司架构,每个公司又有不同的部门树。 现需求为 ```Plain Text 部门树深度不能超过5层,…
扫描二维码继续阅读
2023-11-15