2

我的数据库中有这个表,我想在网页上填充数据。

parent_topic    child_topic
      4             5
      4             6
      4             7
      5             8
      5             9
      5             11
      5             11
      5             13
      12            14
      13            15
      8             16
      8             17
      8             18
      16            19
      9             20
      20            21
      9             22
      9             23
      6             24
      25            25
      24            26
      6             27
      24            25
      25            21

我正在研究python。我应该使用什么算法来填充此表。格式如下...

  • Main Topic 1(没有任何父母的话题)

    • 子主题
      • 子主题
        • 子主题
    • 子主题
  • 主题2
    • 子主题

以此类推...(儿童主题根据表格)。
我试图使用嵌套字典,但我无法创建这样的字典。

提前致谢。

4

3 回答 3

3

我强烈建议您阅读这篇博客在数据库中存储分层数据

该博客详细介绍了工业中关于如何在关系数据库中存储分层数据的两种主要方法:邻接表模型和改进的前序树遍历算法。

邻接表模型方法是您的数据库使用的方法。您通过从顶部节点递归来迭代树。在很多情况下,人们不想或不能将所有数据加载到内存中,因此每个节点上的迭代都会对新的 SQL 查询进行分类。这是邻接表方法的最大缺点。

django-treebeard是一个基于 Django 框架的邻接列表实现高效树实现的库。以为你可能不会使用 django,但你仍然可以从 django 中学到很多东西。

当对树的读取次数大于对树的更改次数时,改进的前序树遍历算法方法更有效(通常对于网站来说是这样),因此它比邻接表方法更受欢迎。

django 也有一个改进的前序树遍历算法的出色实现:django-mptt

于 2013-10-18T15:25:48.377 回答
0

递归方法...

list_pc = [
    (4,5),
    (4,6),
    (4,7),
    (5,8),
    (5,9),
    (5,11),
    (5,11),
    (5,13),
    (12,14),
    (13,15),
    (8,16),
    (8,17),
    (8,18),
    (16,19),
    (9,20),
    (20,21),
    (9,22),
    (9,23),
    (6,24),
    (24,25),
    (24,26),
    (6,27),
    (24,25),
    (25,21),
]

dict_pc = {}
parents = set()
children = set()
for p, c in list_pc:
    parents.add(p)
    children.add(c)
    dict_pc.setdefault(p, []).append(c)

roots = sorted(list(parents - children))
def print_tree(level, p):
    global dict_pc
    print '.'*level, p
    for c in dict_pc.get(p, []):
        print_tree(level + 1, c)

for r in roots:
    print_tree(0, r)

输出:

 4
. 5
.. 8
... 16
.... 19
... 17
... 18
.. 9
... 20
.... 21
... 22
... 23
.. 11
.. 11
.. 13
... 15
. 6
.. 24
... 25
.... 21
... 26
... 25
.... 21
.. 27
. 7
 12
. 14
于 2013-10-18T16:32:53.530 回答
0

对不起我的伪 Python :)

假设您使用返回主题行的方法 get_lines() 列出对象的主题:

def PrintTopic(topic, margin):
    for line in topics[topic].get_lines():
        print "   " * margin + line


def PrintRecursiveTopic(db, currentTopic, depth):
    PrintTopic(currentTopic, depth)
    for topic in db.topics.where(lambda x: x.parent_topic == currentTopic):
        PrintRecursiveTopic(db, topic.child_topic, depth + 1)

depth 用于 PrintTopic 以边距打印

于 2013-10-18T15:12:07.170 回答