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

时间:2008-09-17 01:44:12

标签: php tree

我有一个网络系统,它有一个保存在数据库中的经典父子菜单,字段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解决此问题?

4 个答案:

答案 0 :(得分:2)

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

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

但我还推荐由Joe Celko编写的“SQL for Smarties:高级SQL编程”一书,涵盖嵌套集。

Joe Celko's SQL for Smarties: Advanced SQL Programming

Joe Celko's Trees and Hierarchies in SQL for Smarties

答案 1 :(得分:1)

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

的伪代码:

nodeList = {}
enumerateNodes(rootNode, nodeList);

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

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

答案 2 :(得分:0)

这是一个图形问题。查看BFS(breadth first search)DFS(depth first search).。您可以谷歌这些条款,并在网络上找到数百个实现。

答案 3 :(得分:0)

这对于嵌套集实现来说是微不足道的。有关详细信息,请参见此处:

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