Algorithm 快速获得多链表偏序的算法

Algorithm 快速获得多链表偏序的算法,algorithm,list,linked-list,Algorithm,List,Linked List,我的情况如下: 我有n个双链接列表 每个列表都有一个前哨的开始和结束 所有列表都有相同的开始和结束节点(不是必需的,但为了简单起见) 列表是同质的,可能共享项目 我想找到所有n个列表中所有节点的偏序,从开始节点开始,以结束节点结束,这样,出现在n-x列表中的任何节点,其中x

我的情况如下:

  • 我有n个双链接列表
  • 每个列表都有一个前哨的开始和结束
  • 所有列表都有相同的开始和结束节点(不是必需的,但为了简单起见)
  • 列表是同质的,可能共享项目
我想找到所有n个列表中所有节点的偏序,从开始节点开始,以结束节点结束,这样,出现在n-x列表中的任何节点,其中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的某个地方有一个快得多的版本

(在你问之前,这不是家庭作业或Euler项目,我不能再具体化了。这是问题所在。)


编辑:我相对确信,只有当端点位于所有列表中且位置相同(开始和结束)时,才会定义偏序。我不反对用线性时间搜索来找到这些端点,如果找不到,那么可能会出现错误。

要么我误解了,要么alienhard的算法可能会失败。(我想加上这个作为评论,但我太新了,无法评论。)

考虑这个例子:

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。

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

pick a node from `L`, 
do some operations (explained later), 
and move the chosen node to the `F` list. 
在“执行一些操作步骤”中


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

如果列表的顺序有冲突,答案会是什么,例如
first=[a,b]
second=[b,a]
?Antimome:正如上面的编辑中提到的,如果无法获得有效的端点,我宁愿提前提出一个错误。是的,谢谢,你是对的。我还认为,在一些小的情况下,这是失败的。如果它工作得那么简单和快速,那就太好了;)。我已经将我的答案标记为删除。甚至还有一部分是关于偏序的关系。我非常喜欢这个主意,并且能从中看出它的优雅。因此,问题是如何将多个链表(不是多个链表!)有效地转换为DAG。想法?那么第一个列表中的对象
a
不是第二个列表中的对象
a
?我不明白。如果是这种情况,请使用哈希表(或任何类似结构)将每个对象映射到一个公共数字。然后构建DAG。例如
a
=1、
b
=2等。现在,使用1和2来构建DAG,而不是
a
s和
b
s@MostAwesomeDude当前位置我不理解你的问题:任何适用于DAG的东西都必须适用于DAG以外的东西(更确切地说,边缘是双向的)。如果您一直在研究如何将列表转换为图形,那么您已经为该问题做出了一个理想的假设:每个列表中的所有第一个节点都是相等的。因此,这是图形的理想根,每个列表代表一个branchI,但我对转换的复杂性感到困惑,但我可以看到Kahn的算法如何直接处理链表,所以我可以这样做。谢谢
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