【问题标题】:Algorithm for quickly obtaining a partial ordering over multiple linked lists快速获取多链表偏序的算法
【发布时间】:2011-09-17 10:14:13
【问题描述】:

我有一个情况,如下:

  • 我有 n 个双向链表
  • 每个列表都有一个标记开头和结尾
  • 所有列表都有相同的开始和结束节点(不是必需的,但为了简单起见)
  • 列表是同质的,并且可能共享项目

我想在所有 n 列表中找到所有节点的部分排序,从开始节点开始并以结束节点结束,这样出现在 中的任何节点em>nx 个列表,其中 x ,将相对于它出现的所有列表中的其他节点进行排序。

使用数组提供一组示例列表:

first  = [a, b,    d,    f,    h, i];
second = [a, b, c,       f, g,    i];
third  = [a,          e, f, g, h, i];

显然,一个可能的答案是 [a, b, c, d, e, f, g, h, i],但另一种可接受的顺序是 [a, b, d, e, c, f, g , h, i]。

我知道一种快速算法可以做到这一点,有人记得它是怎么做的或叫什么吗?我已经有一些慢版本,但我确信在 Knuth 的某个地方有一个快得多的版本。

(而且,在你问之前,这不是为了家庭作业或欧拉计划,我不能说得更具体。这问题。)

编辑:我相对确定,仅当端点位于所有列表中且位于相同位置(开始和结束)时才定义部分排序。我不会反对使用线性时间搜索来找到这些端点,如果找不到它们,那么那里可能会引发错误。

【问题讨论】:

  • 如果列表有冲突的顺序,答案会是什么,例如first = [a, b]second = [b, a]?
  • antinome:正如上面编辑中提到的,如果无法获得有效的端点,我宁愿提前提出错误。

标签: algorithm list linked-list


【解决方案1】:

要么我理解错了,要么外星哈德的算法可能会失败。 (我会将此添加为评论,但我太新了,无法评论。)

考虑这个例子:

first  = [a, b, c, d,             i];
second = [a,       d, e, f,       i];
third  = [a,             f, g, h, i];

Alienhard 的算法将给出:a=0, b=1, c=2, d=3, e=2, f=3, g=2, h=3, i=4

然后算法要求 e 在 d 之前,即使 e 在 d 之后。

【讨论】:

  • 是的,谢谢,你是对的。我也只是认为有一些微不足道的情况会失败。如果它工作得那么简单和快速,那就太好了;)。我已将我的答案标记为删除。
【解决方案2】:

在我看来与Topological sort 非常相似。有几种算法可以让您获得拓扑排序状态。我特别喜欢的一个类似于广度优先搜索。维护两个列表,一个没有入边的所有节点,比如L(最初只是a 节点),另一个带有部分有序节点,F。现在每一步,

pick a node from `L`, 
do some operations (explained later), 
and move the chosen node to the `F` list. 

在“做一些操作步骤”中,

choose all successors of the source node which have exactly one in-link add them to L.
Remove the link from the source node to all the successors in the previous step 

现在,F 列表已对所有节点进行了拓扑排序。对于糟糕的解释,我很抱歉,wiki 链接有很好的图表 :)

【讨论】:

  • 甚至还有一节是关于部分订单的关系。我非常喜欢这个想法,并且可以看到其中的优雅。那么,问题将是从多个链表(不是多重链接的!)到 DAG 的有效转换。想法?
  • 所以第一个列表中的对象a 不是第二个列表中的对象a?我不跟。如果是这种情况,请使用哈希表(或任何类似结构)将每个对象映射到一个公共数字。然后构建 DAG。例如a = 1、b = 2 等等。现在,使用 1 和 2 代替 as 和 bs 构建你的 DAG
  • @MostAwesomeDude:我不明白你的问题:任何适用于 DAG 的东西肯定都适用于不只是 DAG 的东西(更多的意义在于边缘是双向的)。如果您不知道如何将列表转换为图表,那么您已经为这个问题做了一个理想的假设:每个列表中的所有第一个节点都是相等的。因此,这是您的图表的理想根,每个列表代表一个分支
  • 我只是对转换的复杂性感到困惑,但我可以看到 Kahn 的算法如何直接在链表上工作,所以我可以这样做。谢谢!
猜你喜欢
  • 2018-05-22
  • 1970-01-01
  • 2020-07-01
  • 2012-03-14
  • 1970-01-01
  • 2016-11-24
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多