检索树中所有属于另一节点的子节点

时间:2020-03-05 18:57:41  来源:igfitidea点击:

我有一个Web系统,其中有一个经典的父子菜单保存在数据库中,字段id为PK,parent_id指向拥有的菜单。 (是的,我知道这不能很好地扩展,但这是另一个主题)。

因此,对于这些记录(id-parent_id对):

0-7 0-4 4-9 4-14 4-16 9-6

我有这棵树:

0
├ 7
└ 4
  ├ 9
  | └ 6     
  ├ 14
  └ 16

我需要隐藏一个顶部节点,因此我必须列出该节点的所有子节点,即对于4,它们将是(9、6、14、16)。顺序无关紧要。

我很困惑...这是否适合经典的树木问题?还是一个图?

如何使用php构成此结构并解决此问题?

解决方案

回答

这是使用递归的绝佳机会!

伪代码:

nodeList = {}
enumerateNodes(rootNode, nodeList);

function enumerateNodes(node, nodeList) {
   nodeList += node;
   foreach ( childnode in node.children ) {
       enumerateNodes(childnode, nodeList);
   }
}

编辑:没注意到树是相邻列表格式。在开始使用它之前,我可能会将其构建到实际的树数据结构中。只需遍历所有对(在我们第一次看到它们时创建节点)并链接它们即可。我认为应该很容易...

回答

相邻列表模型很难处理。我现在所在的公司将它们用于层次结构,这会造成很大的麻烦。我已经为先前的雇主成功地使用了Celko的嵌套集模型,它们对于创建,维护和使用层次结构(树)非常有用。

我找到了描述他们的链接:http://www.intelligententerprise.com/001020/celko.jhtml

但是,我还建议由Joe Celko撰写的书" SQL for Smarties:高级SQL编程",其中涉及嵌套集。

Joe Celko的《 Smarties SQL:高级SQL编程》

聪明人的SQL中的Joe Celko的树和层次结构

回答

这是一个图形问题。查看BFS(深度优先搜索)和DFS(深度优先搜索)。

回答

对于嵌套集实现,这是微不足道的。请参阅此处以获取更多详细信息:

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

否则,编写如下内容:

def get_subtree(node)
  if children.size > 0
    return children.collect { |n| get_subtree(n) }
  else
    return node
  end
end