【问题标题】:What is the difference between modified preorder and just preorder?修改后的预购和仅预购有什么区别?
【发布时间】:2014-04-23 14:47:16
【问题描述】:

我已经阅读了有关树遍历和树数据结构的内容,所以我现在知道什么是预序树遍历,但我也看到有一种叫做修改的预序树遍历的东西,但我发现很难找到好的答案或有关这两者之间区别的文档。有人可以对此发表评论吗?我确实找到了一篇解释它的文章,但图表看起来与常规预购相似,作者写的唯一内容是一个节点有两个附加值,我不确定这是否正确。

我看过的文章:http://imrannazar.com/Modified-Preorder-Tree-Traversal 我也看过这个:http://www.sitepoint.com/hierarchical-data-database-2/ 但我很难相信这位自称是大学经济学专业的作者,他写的是关于树结构的文章。 Django 的 mptt 模块是它被使用的地方之一:http://django-mptt.github.io/django-mptt/overview.html#what-is-modified-preorder-tree-traversal

当我在 google 上搜索时,这个预排序树遍历的修改版本似乎在多个地方被使用,所以我觉得有点奇怪,没有更多的文章解释这些差异。

【问题讨论】:

  • 如果你引用了一篇文章,至少添加一个链接或引用它。 “修改前序”听起来像是有人根据自己的需要修改了前序遍历的概念。
  • 我在很多地方都看到了“修改前序树遍历”这个词,所以它似乎在几个地方都被使用了。我将添加几个链接。

标签: database data-structures tree


【解决方案1】:

我有点不同意这个命名,也许你对此有些困惑。

我将“遍历”定义为遍历的过程。

我们从遍历中得到的结果我可能称之为“表示”

MPTT 与其说是遍历,不如说是一种表示。

另外,左边的值可以被认为是前序,而右边的值可以被认为是后序(我们会讲到...)。

因此我可能更愿意将其命名为“组合的前/后遍历表示”


现在看看这到底是什么。

如上所述,它只是一种表示。

让我们看一下从树中生成这种表示的算法:

traverse(node, index)
   node.left = index

   for each child c of node
     traverse(c, ++index)

   node.right = ++index

从上面的代码可以看出,我们在递归到子节点之前和之后都对节点做了一些事情,所以它可以看作是前后遍历的某种组合。

现在,这与预购或后购之间更显着的区别在于它的使用方式。

前序或后序通常是您在树上运行或用于生成树的东西(也许是为了将其紧凑地存储到磁盘,而当您实际想要使用时,可能会在内存中生成典型的基于指针的表示树)。

但是使用 MPTT,这将是您在使用它时 实际表示树的方式。这在不特别关注递归的数据库中特别有用。

您可以将 MPTT 值存储在表中,这样您就可以高效地执行各种查询。例如:(源自here

  • 要获取节点的所有后代,您需要在该节点的左右值之间查找左值。

  • 要获取节点的/所有祖先的路径,您需要查找左侧值小于此左侧值且右侧值大于此右侧值的节点。

以上两项都可以使用单个查询来执行,其中递归表示将需要对路径中的每个节点进行一次查询,而对后代进行一些查询。

【讨论】:

  • 感谢您的精彩回答。连同图表,我现在可以看到这比常规预购要快得多,效率更高。因此,如果您有一个线程评论系统,例如,您只需执行一个查询,而不是遍历需要更多时间的树。
猜你喜欢
  • 1970-01-01
  • 2012-09-21
  • 2020-06-21
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 2012-11-15
  • 1970-01-01
相关资源
最近更新 更多