我有一个关键字表,其中每个关键字都分配了一个ID并且是唯一的。我有第二个表将父关键字的ID链接到子关键字的ID。一个关键字最多可包含约800个孩子或根本没有。孩子可以成为更多关键词的父母(以及......等等)
我遇到的问题是孩子(或孙子或曾孙子)可能是初始关键字的父亲,导致周期性结构。我正在尝试使用递归函数为初始关键字构建树数据结构,但该函数要么永远不会结束,要么超过Python中的1000级递归限制。
有没有更好的方法来设计我的父/子表来防止这种情况(或者在插入期间进行前期检查)还是有更好的方法来编写递归函数来防止这种情况发生?我试图限制递归函数的深度,但遇到单级问题(即,child是父级的父级)。同样,我的目标是为初始关键字创建树结构。
Table Keyword:
id int(11) not null primary key auto_increment (id of keyword)
text varchar(255) unique (keyword text e.g. "computer help desk")
Table Keyword_Relation:
id int(11) not null primary key auto_increment (id for parent/child combo, not keyword id)
parent int(11) (id of parent keyword)
child int(11) (id of child keyword)
答案 0 :(得分:2)
您要做的是创建拓扑排序。发布了许多方法可以最佳地执行此操作,这取决于您的架构和首选方法。
在你的情况下,听起来你没有多父母。 但是我如何以编程方式处理它是从叶节点(即没有子节点的节点)开始并提升树。 升序时,保留您遇到的节点集合。如果您重复遭遇,则存在循环并且无法进行拓扑排序。
你不会得到一个无限循环,但你的拓扑当然可能有超过1000个节点......所以你可能无法进行递归。
编辑:回答有关“更好设计”的问题....如果可能,存储根节点标识符可能更有利。 那就是:给予父母,孩子,孙子,伟大的孩子,伟大的......孙子
每一行不仅包含立即父级ID,还包含根节点父级ID ...或某些“已知良好”根节点
如果你这样做,你可以加速拓扑排序方法,只提升到根节点,并且只包括具有相同根节点的集合。
答案 1 :(得分:1)
您可以从树的顶部开始,只需跟踪您已找到的节点并忽略它们。
def getchildren(node, ignore_nodes=[]):
child_nodes = []
for child in node.children():
if child in ignore_nodes:
continue
child_nodes.append(child)
ignore_nodes.append(child)
nodes, ignore_nodes = getchildren(child, ignore_nodes)
child_nodes.extend(nodes)
return child_nodes, ignore_nodes