最有效的数据结构来表示Java中的线程注释?

时间:2009-04-17 06:03:55

标签: java data-structures tree reddit threaded-comments

我想在Java中表示线程评论。这与 reddit.com

上的评论方式类似
hello
   hello
      hello
      hello
   hello
   hello
      hello

如上例所示,响应嵌套在HTML中并带有适当的缩进,以反映它们与先前注释的关系。

用Java表示这个有效的方法是什么?

我认为某种树数据结构是合适的。

但是,是否有一个特别是最有效来最小化树遍历?

如果我对每条评论进行投票,这将非常重要。因为在每次投票之后树需要重新排序 - 计算上可能是昂贵的操作。

顺便说一句,如果有人知道Java中的开源现有实现,那也会有所帮助。

3 个答案:

答案 0 :(得分:10)

我会使用链接列表的级别。

message1
    message2
        message3
        message4
    message5
    message6
        message7

每个节点都有一个指向它的指针:

- forward sibling  (2->5, 3->4, 5->6,                   1/4/6/7->NULL).
- backward sibling (4->3, 5->2, 6->5,                   1/2/3/7->NULL).
- first child      (1->2, 2->3, 6->7,                   3/4/5/7->NULL).
- parent           (2->1, 3->2, 4->2, 5->1, 6->1, 7->6,       1->NULL).

在每个级别中,邮件将按照投票计数(或您想要使用的任何其他分数)在列表中排序。

这样可以最大限度地灵活地移动物体,只需更改父级和该级别的链接即可移动整个子树(例如message2)。

例如,假设message6获得大量投票,使其比message5更受欢迎。更改是(调整下一个和上一个兄弟指针):

  • message2 -> message6
  • message6 -> message5
  • message5 -> NULL

得到:

message1
    message2
        message3
        message4
    message6
        message7
    message5

如果它继续获得比message2更多的选票,则会发生以下情况:

  • message6 -> message2
  • message2 -> message5

AND message1的第一个子指针设置为message6(它是message2),仍然相对容易获得:

message1
    message6
        message7
    message2
        message3
        message4
    message5

只有当分数变化导致消息变得超过其兄弟姐妹或低于其兄弟姐妹时,才需要重新排序。每次分数变化后,您无需重新订购。

答案 1 :(得分:4)

树是正确的(使用getLastSibling和getNextSibling),但是如果您正在存储/查询数据,您可能希望为每个条目存储一个谱系,或者通过前序遍历来存储数字:

http://www.sitepoint.com/article/hierarchical-data-database/2/

如果丢失了确切的子节点数,您可以留出空隙以最小化重新编号。尽管如此,我不确定这会明显快于每次遍历树。我想这取决于你的树有多深。

另见:

SQL - How to store and navigate hierarchies? http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html(此计划也称为Celko树)

答案 2 :(得分:0)

  

如果我对每条评论进行投票,这将非常重要。因为在每次投票之后树需要重新排序 - 计算上可能是昂贵的操作。

听起来像是对我来说过早优化,甚至可能是错误的优化。

您的树数据结构听起来很合理,可用于表示您的数据。我说坚持下去。只有在检测到并测量到性能问题时才能对其进行优化,并且可以与替代方案进行比较。