我有一个网络系统,它有一个保存在数据库中的经典父子菜单,字段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解决此问题?
答案 0 :(得分:2)
相邻的列表模型很难处理。我现在所在的公司将它们用于层次结构,这会引起很大的麻烦。我已经成功地为先前的雇主使用了Celko的嵌套集模型,并且它们非常适合创建,维护和使用层次结构(树)。
我找到了这个描述它们的链接:http://www.intelligententerprise.com/001020/celko.jhtml
但我还推荐由Joe Celko编写的“SQL for Smarties:高级SQL编程”一书,涵盖嵌套集。
答案 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